diff --git a/examples/files.js b/examples/files.js index 32adbd226fad8696c9e71b01a464415ee198807a..6aa8509b44d825006d9c05a24445213f4a6afb22 100644 --- a/examples/files.js +++ b/examples/files.js @@ -209,6 +209,7 @@ var files = { "webgl_panorama_equirectangular", "webgl_performance", "webgl_performance_doublesided", + "webgl_performance_nodes", "webgl_performance_static", "webgl_physics_cloth", "webgl_physics_convex_break", @@ -232,6 +233,7 @@ var files = { "webgl_postprocessing_ssaa", "webgl_postprocessing_ssaa_unbiased", "webgl_postprocessing_nodes", + "webgl_postprocessing_nodes_pass", "webgl_postprocessing_outline", "webgl_postprocessing_pixel", "webgl_postprocessing_procedural", diff --git a/examples/js/nodes/Nodes.js b/examples/js/nodes/Nodes.js index a45536bd8fe6e65894fde94b6fa93c8a03632b95..5b8a74ee40cec2f2d21c3cb55bbf8017573dd6fb 100644 --- a/examples/js/nodes/Nodes.js +++ b/examples/js/nodes/Nodes.js @@ -2,7 +2,7 @@ // core -export { GLNode } from './core/GLNode.js'; +export { Node } from './core/Node.js'; export { TempNode } from './core/TempNode.js'; export { InputNode } from './core/InputNode.js'; export { ConstNode } from './core/ConstNode.js'; @@ -10,6 +10,7 @@ export { VarNode } from './core/VarNode.js'; export { StructNode } from './core/StructNode.js'; export { AttributeNode } from './core/AttributeNode.js'; export { FunctionNode } from './core/FunctionNode.js'; +export { ExpressionNode } from './core/ExpressionNode.js'; export { FunctionCallNode } from './core/FunctionCallNode.js'; export { NodeLib } from './core/NodeLib.js'; export { NodeUtils } from './core/NodeUtils.js'; @@ -32,6 +33,7 @@ export { CubeTextureNode } from './inputs/CubeTextureNode.js'; export { ScreenNode } from './inputs/ScreenNode.js'; export { ReflectorNode } from './inputs/ReflectorNode.js'; export { PropertyNode } from './inputs/PropertyNode.js'; +export { RTTNode } from './inputs/RTTNode.js'; // accessors @@ -51,10 +53,12 @@ export { Math1Node } from './math/Math1Node.js'; export { Math2Node } from './math/Math2Node.js'; export { Math3Node } from './math/Math3Node.js'; export { OperatorNode } from './math/OperatorNode.js'; +export { CondNode } from './math/CondNode.js'; // procedural export { NoiseNode } from './procedural/NoiseNode.js'; +export { CheckerNode } from './procedural/CheckerNode.js'; // bsdfs @@ -78,6 +82,7 @@ export { TimerNode } from './utils/TimerNode.js'; export { VelocityNode } from './utils/VelocityNode.js'; export { UVTransformNode } from './utils/UVTransformNode.js'; export { MaxMIPLevelNode } from './utils/MaxMIPLevelNode.js'; +export { ColorSpaceNode } from './utils/ColorSpaceNode.js'; // effects @@ -103,4 +108,5 @@ export { MeshStandardNodeMaterial } from './materials/MeshStandardNodeMaterial.j // postprocessing +export { NodePostProcessing } from './postprocessing/NodePostProcessing.js'; //export { NodePass } from './postprocessing/NodePass.js'; diff --git a/examples/js/nodes/THREE.Nodes.js b/examples/js/nodes/THREE.Nodes.js index a81f74c6fcfc6e60a8679d609f9f6bb3fafc40df..e517f3e25eac2165fbeec1ecf238b537490e4f85 100644 --- a/examples/js/nodes/THREE.Nodes.js +++ b/examples/js/nodes/THREE.Nodes.js @@ -1,8 +1,8 @@ -import { +import { // core - - GLNode, + + Node, TempNode, InputNode, ConstNode, @@ -10,15 +10,16 @@ import { StructNode, AttributeNode, FunctionNode, + ExpressionNode, FunctionCallNode, NodeLib, NodeUtils, NodeFrame, NodeUniform, NodeBuilder, - + // inputs - + IntNode, FloatNode, Vector2Node, @@ -32,9 +33,10 @@ import { ScreenNode, ReflectorNode, PropertyNode, - + RTTNode, + // accessors - + UVNode, ColorsNode, PositionNode, @@ -44,33 +46,35 @@ import { ReflectNode, ScreenUVNode, ResolutionNode, - + // math - + Math1Node, Math2Node, Math3Node, OperatorNode, - + CondNode, + // procedural - + NoiseNode, - + CheckerNode, + // bsdfs - + BlinnShininessExponentNode, BlinnExponentToRoughnessNode, RoughnessToBlinnExponentNode, - + // misc - + TextureCubeUVNode, TextureCubeNode, NormalMapNode, BumpMapNode, - + // utils - + BypassNode, JoinNode, SwitchNode, @@ -78,34 +82,39 @@ import { VelocityNode, UVTransformNode, MaxMIPLevelNode, - + ColorSpaceNode, + // effects - + BlurNode, ColorAdjustmentNode, LuminanceNode, // material nodes - + RawNode, SpriteNode, PhongNode, StandardNode, MeshStandardNode, - + // materials - + NodeMaterial, SpriteNodeMaterial, PhongNodeMaterial, StandardNodeMaterial, - MeshStandardNodeMaterial - + MeshStandardNodeMaterial, + + // post-processing + + NodePostProcessing + } from './Nodes.js'; // core -THREE.GLNode = GLNode; +THREE.Node = Node; THREE.TempNode = TempNode; THREE.InputNode = InputNode; THREE.ConstNode = ConstNode; @@ -113,6 +122,7 @@ THREE.VarNode = VarNode; THREE.StructNode = StructNode; THREE.AttributeNode = AttributeNode; THREE.FunctionNode = FunctionNode; +THREE.ExpressionNode = ExpressionNode; THREE.FunctionCallNode = FunctionCallNode; THREE.NodeLib = NodeLib; THREE.NodeUtils = NodeUtils; @@ -135,6 +145,7 @@ THREE.CubeTextureNode = CubeTextureNode; THREE.ScreenNode = ScreenNode; THREE.ReflectorNode = ReflectorNode; THREE.PropertyNode = PropertyNode; +THREE.RTTNode = RTTNode; // accessors @@ -154,10 +165,12 @@ THREE.Math1Node = Math1Node; THREE.Math2Node = Math2Node; THREE.Math3Node = Math3Node; THREE.OperatorNode = OperatorNode; +THREE.CondNode = CondNode; // procedural THREE.NoiseNode = NoiseNode; +THREE.CheckerNode = CheckerNode; // bsdfs @@ -181,6 +194,7 @@ THREE.TimerNode = TimerNode; THREE.VelocityNode = VelocityNode; THREE.UVTransformNode = UVTransformNode; THREE.MaxMIPLevelNode = MaxMIPLevelNode; +THREE.ColorSpaceNode = ColorSpaceNode; // effects @@ -203,3 +217,7 @@ THREE.SpriteNodeMaterial = SpriteNodeMaterial; THREE.PhongNodeMaterial = PhongNodeMaterial; THREE.StandardNodeMaterial = StandardNodeMaterial; THREE.MeshStandardNodeMaterial = MeshStandardNodeMaterial; + +// post-processing + +THREE.NodePostProcessing = NodePostProcessing; diff --git a/examples/js/nodes/accessors/CameraNode.js b/examples/js/nodes/accessors/CameraNode.js index f9cc9df69e09d8b9cc6bc82ef1c61d3f1093d7ce..d9f503d57c134a7104a5a650b6424316d72505b1 100644 --- a/examples/js/nodes/accessors/CameraNode.js +++ b/examples/js/nodes/accessors/CameraNode.js @@ -6,7 +6,7 @@ import { TempNode } from '../core/TempNode.js'; import { FunctionNode } from '../core/FunctionNode.js'; import { FloatNode } from '../inputs/FloatNode.js'; import { PositionNode } from '../accessors/PositionNode.js'; - + function CameraNode( scope, camera ) { TempNode.call( this, 'v3' ); @@ -14,33 +14,33 @@ function CameraNode( scope, camera ) { this.setScope( scope || CameraNode.POSITION ); this.setCamera( camera ); -}; +} + +CameraNode.Nodes = ( function () { -CameraNode.Nodes = (function() { - var depthColor = new FunctionNode( [ "float depthColor( float mNear, float mFar ) {", - + " #ifdef USE_LOGDEPTHBUF_EXT", - + " float depth = gl_FragDepthEXT / gl_FragCoord.w;", - + " #else", - + " float depth = gl_FragCoord.z / gl_FragCoord.w;", - + " #endif", - + " return 1.0 - smoothstep( mNear, mFar, depth );", - + "}" ].join( "\n" ) ); - + return { depthColor: depthColor }; - -})(); + +} )(); CameraNode.POSITION = 'position'; CameraNode.DEPTH = 'depth'; @@ -92,7 +92,7 @@ CameraNode.prototype.getType = function ( builder ) { switch ( this.scope ) { case CameraNode.DEPTH: - + return 'f'; } @@ -107,7 +107,7 @@ CameraNode.prototype.isUnique = function ( builder ) { case CameraNode.DEPTH: case CameraNode.TO_VERTEX: - + return true; } @@ -121,7 +121,7 @@ CameraNode.prototype.isShared = function ( builder ) { switch ( this.scope ) { case CameraNode.POSITION: - + return false; } @@ -180,15 +180,15 @@ CameraNode.prototype.onUpdateFrame = function ( frame ) { }; CameraNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.setScope( source.scope ); if ( source.camera ) { - + this.setCamera( source.camera ); - + } switch ( source.scope ) { @@ -201,7 +201,7 @@ CameraNode.prototype.copy = function ( source ) { break; } - + }; CameraNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/accessors/ColorsNode.js b/examples/js/nodes/accessors/ColorsNode.js index 14d3738ed035fbcf45378d33284220275d3c5c8c..2586d1556f12aeb1e7fe847b9c98220bbda6c534 100644 --- a/examples/js/nodes/accessors/ColorsNode.js +++ b/examples/js/nodes/accessors/ColorsNode.js @@ -1,20 +1,19 @@ /** * @author sunag / http://www.sunag.com.br/ */ - + import { TempNode } from '../core/TempNode.js'; -import { NodeLib } from '../core/NodeLib.js'; - + var vertexDict = [ 'color', 'color2' ], fragmentDict = [ 'vColor', 'vColor2' ]; - + function ColorsNode( index ) { TempNode.call( this, 'v4', { shared: false } ); this.index = index || 0; -}; +} ColorsNode.prototype = Object.create( TempNode.prototype ); ColorsNode.prototype.constructor = ColorsNode; @@ -30,11 +29,11 @@ ColorsNode.prototype.generate = function ( builder, output ) { }; ColorsNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.index = source.index; - + }; ColorsNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/accessors/LightNode.js b/examples/js/nodes/accessors/LightNode.js index 55aaba8d415be5c3573e0889f8cad2f44cdee878..f510329f105017c7911d628d6334b4ed94659ee8 100644 --- a/examples/js/nodes/accessors/LightNode.js +++ b/examples/js/nodes/accessors/LightNode.js @@ -10,7 +10,7 @@ function LightNode( scope ) { this.scope = scope || LightNode.TOTAL; -}; +} LightNode.TOTAL = 'total'; @@ -22,24 +22,24 @@ LightNode.prototype.generate = function ( builder, output ) { if ( builder.isCache( 'light' ) ) { - return builder.format( 'reflectedLight.directDiffuse', this.getType( builder ), output ); + return builder.format( 'reflectedLight.directDiffuse', this.type, output ); } else { console.warn( "THREE.LightNode is only compatible in \"light\" channel." ); - return builder.format( 'vec3( 0.0 )', this.getType( builder ), output ); + return builder.format( 'vec3( 0.0 )', this.type, output ); } }; LightNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.scope = source.scope; - + }; LightNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/accessors/NormalNode.js b/examples/js/nodes/accessors/NormalNode.js index d2936f399b8a19316c3f22de59802a18ba2a6dc2..db254097098e3d19216a2aa8331dc2387ae07bad 100644 --- a/examples/js/nodes/accessors/NormalNode.js +++ b/examples/js/nodes/accessors/NormalNode.js @@ -4,14 +4,14 @@ import { TempNode } from '../core/TempNode.js'; import { NodeLib } from '../core/NodeLib.js'; - + function NormalNode( scope ) { TempNode.call( this, 'v3' ); this.scope = scope || NormalNode.LOCAL; -}; +} NormalNode.LOCAL = 'local'; NormalNode.WORLD = 'world'; @@ -45,7 +45,7 @@ NormalNode.prototype.generate = function ( builder, output ) { builder.requires.normal = true; - result = builder.isShader( 'vertex' ) ? 'normal' : 'vObjectNormal'; + result = 'normal'; break; @@ -54,7 +54,7 @@ NormalNode.prototype.generate = function ( builder, output ) { builder.requires.worldNormal = true; result = builder.isShader( 'vertex' ) ? '( modelMatrix * vec4( objectNormal, 0.0 ) ).xyz' : 'vWNormal'; - + break; case NormalNode.VIEW: @@ -70,11 +70,11 @@ NormalNode.prototype.generate = function ( builder, output ) { }; NormalNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.scope = source.scope; - + }; NormalNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/accessors/PositionNode.js b/examples/js/nodes/accessors/PositionNode.js index c57814c74f24824d51e45044f8e6c0b3eedc0d8c..e81ff9b39765e28e63db4a9def3f44dacc69fe6e 100644 --- a/examples/js/nodes/accessors/PositionNode.js +++ b/examples/js/nodes/accessors/PositionNode.js @@ -4,14 +4,14 @@ import { TempNode } from '../core/TempNode.js'; import { NodeLib } from '../core/NodeLib.js'; - + function PositionNode( scope ) { TempNode.call( this, 'v3' ); this.scope = scope || PositionNode.LOCAL; -}; +} PositionNode.LOCAL = 'local'; PositionNode.WORLD = 'world'; @@ -22,12 +22,12 @@ PositionNode.prototype = Object.create( TempNode.prototype ); PositionNode.prototype.constructor = PositionNode; PositionNode.prototype.nodeType = "Position"; -PositionNode.prototype.getType = function ( builder ) { +PositionNode.prototype.getType = function ( ) { switch ( this.scope ) { case PositionNode.PROJECTION: - + return 'v4'; } @@ -42,7 +42,7 @@ PositionNode.prototype.isShared = function ( builder ) { case PositionNode.LOCAL: case PositionNode.WORLD: - + return false; } @@ -92,11 +92,11 @@ PositionNode.prototype.generate = function ( builder, output ) { }; PositionNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.scope = source.scope; - + }; PositionNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/accessors/ReflectNode.js b/examples/js/nodes/accessors/ReflectNode.js index 843f10d637054a595d0a937c640b1b96bf500fe4..bc6cc7b171812d0a1840c03f1d3d696725a55464 100644 --- a/examples/js/nodes/accessors/ReflectNode.js +++ b/examples/js/nodes/accessors/ReflectNode.js @@ -10,7 +10,7 @@ function ReflectNode( scope ) { this.scope = scope || ReflectNode.CUBE; -}; +} ReflectNode.CUBE = 'cube'; ReflectNode.SPHERE = 'sphere'; @@ -37,7 +37,7 @@ ReflectNode.prototype.getType = function ( builder ) { ReflectNode.prototype.generate = function ( builder, output ) { if ( builder.isShader( 'fragment' ) ) { - + var result; switch ( this.scope ) { @@ -72,14 +72,14 @@ ReflectNode.prototype.generate = function ( builder, output ) { } - return builder.format( result, this.getType( this.type ), output ); - + return builder.format( result, this.getType( builder ), output ); + } else { - + console.warn( "THREE.ReflectNode is not compatible with " + builder.shader + " shader." ); return builder.format( 'vec3( 0.0 )', this.type, output ); - + } }; diff --git a/examples/js/nodes/accessors/ResolutionNode.js b/examples/js/nodes/accessors/ResolutionNode.js index 8602c56a7d0b29dbdc0189299ecb289a6d45b44e..c6225bc75da5807c93ef0dce49ddd7627d883e0c 100644 --- a/examples/js/nodes/accessors/ResolutionNode.js +++ b/examples/js/nodes/accessors/ResolutionNode.js @@ -3,14 +3,12 @@ */ import { Vector2Node } from '../inputs/Vector2Node.js'; - -function ResolutionNode( renderer ) { - Vector2Node.call( this ); +function ResolutionNode() { - this.renderer = renderer; + Vector2Node.call( this ); -}; +} ResolutionNode.prototype = Object.create( Vector2Node.prototype ); ResolutionNode.prototype.constructor = ResolutionNode; @@ -18,20 +16,28 @@ ResolutionNode.prototype.nodeType = "Resolution"; ResolutionNode.prototype.updateFrame = function ( frame ) { - var size = this.renderer.getSize(), - pixelRatio = this.renderer.getPixelRatio(); + if ( frame.renderer ) { + + var size = frame.renderer.getSize(), + pixelRatio = frame.renderer.getPixelRatio(); + + this.x = size.width * pixelRatio; + this.y = size.height * pixelRatio; + + } else { - this.x = size.width * pixelRatio; - this.y = size.height * pixelRatio; + console.warn( "ResolutionNode need a renderer in NodeFrame" ); + + } }; ResolutionNode.prototype.copy = function ( source ) { - + Vector2Node.prototype.copy.call( this, source ); - + this.renderer = source.renderer; - + }; ResolutionNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/accessors/ScreenUVNode.js b/examples/js/nodes/accessors/ScreenUVNode.js index b153b0d04c0038d53a73f031778cc8cc47c581a9..a2aac5f0108f8dce48daff00ad4f2b1c540b5796 100644 --- a/examples/js/nodes/accessors/ScreenUVNode.js +++ b/examples/js/nodes/accessors/ScreenUVNode.js @@ -3,14 +3,15 @@ */ import { TempNode } from '../core/TempNode.js'; - +import { ResolutionNode } from './ResolutionNode.js'; + function ScreenUVNode( resolution ) { TempNode.call( this, 'v2' ); - this.resolution = resolution; + this.resolution = resolution || new ResolutionNode(); -}; +} ScreenUVNode.prototype = Object.create( TempNode.prototype ); ScreenUVNode.prototype.constructor = ScreenUVNode; @@ -37,11 +38,11 @@ ScreenUVNode.prototype.generate = function ( builder, output ) { }; ScreenUVNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.resolution = source.resolution; - + }; ScreenUVNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/accessors/UVNode.js b/examples/js/nodes/accessors/UVNode.js index 529d82d028f27e273a128e34b6298f398203bfab..2753d1fe30ce9dcc71a2f0a80132a15c10fe93d7 100644 --- a/examples/js/nodes/accessors/UVNode.js +++ b/examples/js/nodes/accessors/UVNode.js @@ -4,17 +4,17 @@ import { TempNode } from '../core/TempNode.js'; import { NodeLib } from '../core/NodeLib.js'; - + var vertexDict = [ 'uv', 'uv2' ], fragmentDict = [ 'vUv', 'vUv2' ]; - + function UVNode( index ) { TempNode.call( this, 'v2', { shared: false } ); this.index = index || 0; -}; +} UVNode.prototype = Object.create( TempNode.prototype ); UVNode.prototype.constructor = UVNode; @@ -31,11 +31,11 @@ UVNode.prototype.generate = function ( builder, output ) { }; UVNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.index = source.index; - + }; UVNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/bsdfs/BlinnExponentToRoughnessNode.js b/examples/js/nodes/bsdfs/BlinnExponentToRoughnessNode.js index 3993681f02138f9cc63982948693ed5f856f0d15..d5d429085ef2841553c97a0410e6880481fb4f3f 100644 --- a/examples/js/nodes/bsdfs/BlinnExponentToRoughnessNode.js +++ b/examples/js/nodes/bsdfs/BlinnExponentToRoughnessNode.js @@ -11,7 +11,7 @@ function BlinnExponentToRoughnessNode( blinnExponent ) { this.blinnExponent = blinnExponent || new BlinnShininessExponentNode(); -}; +} BlinnExponentToRoughnessNode.prototype = Object.create( TempNode.prototype ); BlinnExponentToRoughnessNode.prototype.constructor = BlinnExponentToRoughnessNode; @@ -24,11 +24,11 @@ BlinnExponentToRoughnessNode.prototype.generate = function ( builder, output ) { }; BlinnExponentToRoughnessNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.blinnExponent = source.blinnExponent; - + }; BlinnExponentToRoughnessNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/bsdfs/BlinnShininessExponentNode.js b/examples/js/nodes/bsdfs/BlinnShininessExponentNode.js index 607694ec1aa02e2c14c44466ac9b3977b2e8bb39..b21e7d0ca3ead813aa3abe65f3d821616efa20b0 100644 --- a/examples/js/nodes/bsdfs/BlinnShininessExponentNode.js +++ b/examples/js/nodes/bsdfs/BlinnShininessExponentNode.js @@ -8,7 +8,7 @@ function BlinnShininessExponentNode() { TempNode.call( this, 'f' ); -}; +} BlinnShininessExponentNode.prototype = Object.create( TempNode.prototype ); BlinnShininessExponentNode.prototype.constructor = BlinnShininessExponentNode; diff --git a/examples/js/nodes/bsdfs/RoughnessToBlinnExponentNode.js b/examples/js/nodes/bsdfs/RoughnessToBlinnExponentNode.js index adea43fcf375455dc23603c19f724fa271ce515d..e0811d70d2ec9a4a9dee4c1bd432350df8019a71 100644 --- a/examples/js/nodes/bsdfs/RoughnessToBlinnExponentNode.js +++ b/examples/js/nodes/bsdfs/RoughnessToBlinnExponentNode.js @@ -6,7 +6,7 @@ import { TempNode } from '../core/TempNode.js'; import { FunctionNode } from '../core/FunctionNode.js'; import { MaxMIPLevelNode } from '../utils/MaxMIPLevelNode.js'; import { BlinnShininessExponentNode } from './BlinnShininessExponentNode.js'; - + function RoughnessToBlinnExponentNode( texture ) { TempNode.call( this, 'f' ); @@ -16,9 +16,9 @@ function RoughnessToBlinnExponentNode( texture ) { this.maxMIPLevel = new MaxMIPLevelNode( texture ); this.blinnShininessExponent = new BlinnShininessExponentNode(); -}; +} -RoughnessToBlinnExponentNode.Nodes = (function() { +RoughnessToBlinnExponentNode.Nodes = ( function () { var getSpecularMIPLevel = new FunctionNode( [ // taken from here: http://casual-effects.blogspot.ca/2011/08/plausible-environment-lighting-in-two.html @@ -27,18 +27,19 @@ RoughnessToBlinnExponentNode.Nodes = (function() { // float envMapWidth = pow( 2.0, maxMIPLevelScalar ); // float desiredMIPLevel = log2( envMapWidth * sqrt( 3.0 ) ) - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 ); - " float desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );", + " float desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );", // clamp to allowable LOD ranges. " return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );", + "}" ].join( "\n" ) ); - + return { getSpecularMIPLevel: getSpecularMIPLevel }; - -})(); + +} )(); RoughnessToBlinnExponentNode.prototype = Object.create( TempNode.prototype ); RoughnessToBlinnExponentNode.prototype.constructor = RoughnessToBlinnExponentNode; @@ -49,7 +50,7 @@ RoughnessToBlinnExponentNode.prototype.generate = function ( builder, output ) { if ( builder.isShader( 'fragment' ) ) { this.maxMIPLevel.texture = this.texture; - + var getSpecularMIPLevel = builder.include( RoughnessToBlinnExponentNode.Nodes.getSpecularMIPLevel ); return builder.format( getSpecularMIPLevel + '( ' + this.blinnShininessExponent.build( builder, 'f' ) + ', ' + this.maxMIPLevel.build( builder, 'f' ) + ' )', this.type, output ); @@ -65,11 +66,11 @@ RoughnessToBlinnExponentNode.prototype.generate = function ( builder, output ) { }; RoughnessToBlinnExponentNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.texture = source.texture; - + }; RoughnessToBlinnExponentNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/core/AttributeNode.js b/examples/js/nodes/core/AttributeNode.js index 46950351b8ec160367fa0260cd021639d948d9bf..7941d0eaa74f8ac34038665c6f892f6f9a3720ac 100644 --- a/examples/js/nodes/core/AttributeNode.js +++ b/examples/js/nodes/core/AttributeNode.js @@ -2,17 +2,17 @@ * @author sunag / http://www.sunag.com.br/ */ -import { GLNode } from './GLNode.js'; +import { Node } from './Node.js'; function AttributeNode( name, type ) { - GLNode.call( this, type ); + Node.call( this, type ); this.name = name; -}; +} -AttributeNode.prototype = Object.create( GLNode.prototype ); +AttributeNode.prototype = Object.create( Node.prototype ); AttributeNode.prototype.constructor = AttributeNode; AttributeNode.prototype.nodeType = "Attribute"; @@ -38,17 +38,17 @@ AttributeNode.prototype.generate = function ( builder, output ) { name = builder.isShader( 'vertex' ) ? this.name : attribute.varying.name; console.log( attribute ); - + return builder.format( name, this.getType( builder ), output ); }; AttributeNode.prototype.copy = function ( source ) { - - GLNode.prototype.copy.call( this, source ); - + + Node.prototype.copy.call( this, source ); + this.type = source.type; - + }; AttributeNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/core/ConstNode.js b/examples/js/nodes/core/ConstNode.js index df40125bc34477b6607adf7da198012f653c8816..8736b86f26746544210bf2563ef1d4ebe40b1647 100644 --- a/examples/js/nodes/core/ConstNode.js +++ b/examples/js/nodes/core/ConstNode.js @@ -4,13 +4,15 @@ import { TempNode } from './TempNode.js'; +var declarationRegexp = /^([a-z_0-9]+)\s([a-z_0-9]+)\s?\=?\s?(.*?)(\;|$)/i; + function ConstNode( src, useDefine ) { TempNode.call( this ); this.eval( src || ConstNode.PI, useDefine ); -}; +} ConstNode.PI = 'PI'; ConstNode.PI2 = 'PI2'; @@ -19,8 +21,6 @@ ConstNode.RECIPROCAL_PI2 = 'RECIPROCAL_PI2'; ConstNode.LOG2 = 'LOG2'; ConstNode.EPSILON = 'EPSILON'; -ConstNode.rDeclaration = /^([a-z_0-9]+)\s([a-z_0-9]+)\s?\=?\s?(.*?)(\;|$)/i; - ConstNode.prototype = Object.create( TempNode.prototype ); ConstNode.prototype.constructor = ConstNode; ConstNode.prototype.nodeType = "Const"; @@ -37,9 +37,9 @@ ConstNode.prototype.eval = function ( src, useDefine ) { var name, type, value = ""; - var match = this.src.match( ConstNode.rDeclaration ); + var match = this.src.match( declarationRegexp ); - this.useDefine = useDefine || this.src.charAt(0) === '#'; + this.useDefine = useDefine || this.src.charAt( 0 ) === '#'; if ( match && match.length > 1 ) { @@ -74,10 +74,10 @@ ConstNode.prototype.build = function ( builder, output ) { return 'const ' + this.type + ' ' + this.name + ' = ' + this.value + ';'; - } else if (this.useDefine) { - + } else if ( this.useDefine ) { + return this.src; - + } } else { @@ -97,11 +97,11 @@ ConstNode.prototype.generate = function ( builder, output ) { }; ConstNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - - this.eval( source.src, source.useDefine ); - + + this.eval( source.src, source.useDefine ); + }; ConstNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/core/ExpressionNode.js b/examples/js/nodes/core/ExpressionNode.js new file mode 100644 index 0000000000000000000000000000000000000000..064d00bc3e34e4a09bff35c9eb69cdc794fe6000 --- /dev/null +++ b/examples/js/nodes/core/ExpressionNode.js @@ -0,0 +1,17 @@ +/** + * @author sunag / http://www.sunag.com.br/ + */ + +import { FunctionNode } from './FunctionNode.js'; + +function ExpressionNode( src, type, keywords, extensions, includes ) { + + FunctionNode.call( this, src, includes, extensions, keywords, type ); + +} + +ExpressionNode.prototype = Object.create( FunctionNode.prototype ); +ExpressionNode.prototype.constructor = ExpressionNode; +ExpressionNode.prototype.nodeType = "Expression"; + +export { ExpressionNode }; diff --git a/examples/js/nodes/core/FunctionCallNode.js b/examples/js/nodes/core/FunctionCallNode.js index 075542d6936a84122a9e8e8d976bf6fa30b6d7c4..bc541789565819bd8e6ec6d77ba59989b56b1136 100644 --- a/examples/js/nodes/core/FunctionCallNode.js +++ b/examples/js/nodes/core/FunctionCallNode.js @@ -3,14 +3,14 @@ */ import { TempNode } from './TempNode.js'; - + function FunctionCallNode( func, inputs ) { TempNode.call( this ); this.setFunction( func, inputs ); -}; +} FunctionCallNode.prototype = Object.create( TempNode.prototype ); FunctionCallNode.prototype.constructor = FunctionCallNode; @@ -59,9 +59,9 @@ FunctionCallNode.prototype.generate = function ( builder, output ) { }; FunctionCallNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + for ( var prop in source.inputs ) { this.inputs[ prop ] = source.inputs[ prop ]; @@ -69,7 +69,7 @@ FunctionCallNode.prototype.copy = function ( source ) { } this.value = source.value; - + }; FunctionCallNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/core/FunctionNode.js b/examples/js/nodes/core/FunctionNode.js index 18cb7c1c1241df4a2fdf8a996442e7aabd7ba798..a183b321054a20fea9a1758db4442ab7f53926e7 100644 --- a/examples/js/nodes/core/FunctionNode.js +++ b/examples/js/nodes/core/FunctionNode.js @@ -6,32 +6,25 @@ import { TempNode } from './TempNode.js'; import { NodeLib } from './NodeLib.js'; -function FunctionNode( src, includesOrType, extensionsOrKeywords, keywordsOrExtensions, includes ) { +var declarationRegexp = /^([a-z_0-9]+)\s([a-z_0-9]+)\s*\((.*?)\)/i, + propertiesRegexp = /[a-z_0-9]+/ig; - this.isMethod = typeof includesOrType !== "string"; - this.useKeywords = true; +function FunctionNode( src, includes, extensions, keywords, type ) { - TempNode.call( this, this.isMethod ? null : includesOrType ); + this.isMethod = type === undefined; - if ( this.isMethod ) { - - this.eval( src, includesOrType, extensionsOrKeywords, keywordsOrExtensions ); - - } else { - - this.eval( src, includes, keywordsOrExtensions, extensionsOrKeywords ); - - } + TempNode.call( this, type ); -}; + this.eval( src, includes, extensions, keywords ); -FunctionNode.rDeclaration = /^([a-z_0-9]+)\s([a-z_0-9]+)\s*\((.*?)\)/i; -FunctionNode.rProperties = /[a-z_0-9]+/ig; +} FunctionNode.prototype = Object.create( TempNode.prototype ); FunctionNode.prototype.constructor = FunctionNode; FunctionNode.prototype.nodeType = "Function"; +FunctionNode.prototype.useKeywords = true; + FunctionNode.prototype.isShared = function ( builder, output ) { return ! this.isMethod; @@ -50,9 +43,12 @@ FunctionNode.prototype.getInputByName = function ( name ) { while ( i -- ) { - if ( this.inputs[ i ].name === name ) + if ( this.inputs[ i ].name === name ) { + return this.inputs[ i ]; + } + } }; @@ -63,9 +59,12 @@ FunctionNode.prototype.getIncludeByName = function ( name ) { while ( i -- ) { - if ( this.includes[ i ].name === name ) + if ( this.includes[ i ].name === name ) { + return this.includes[ i ]; + } + } }; @@ -86,9 +85,9 @@ FunctionNode.prototype.generate = function ( builder, output ) { } - while ( match = FunctionNode.rProperties.exec( this.src ) ) { + while ( match = propertiesRegexp.exec( this.src ) ) { - var prop = match[ 0 ], + var prop = match[ 0 ], isGlobal = this.isMethod ? ! this.getInputByName( prop ) : true, reference = prop; @@ -156,7 +155,7 @@ FunctionNode.prototype.eval = function ( src, includes, extensions, keywords ) { if ( this.isMethod ) { - var match = this.src.match( FunctionNode.rDeclaration ); + var match = this.src.match( declarationRegexp ); this.inputs = []; @@ -165,7 +164,7 @@ FunctionNode.prototype.eval = function ( src, includes, extensions, keywords ) { this.type = match[ 1 ]; this.name = match[ 2 ]; - var inputs = match[ 3 ].match( FunctionNode.rProperties ); + var inputs = match[ 3 ].match( propertiesRegexp ); if ( inputs ) { @@ -211,16 +210,16 @@ FunctionNode.prototype.eval = function ( src, includes, extensions, keywords ) { }; FunctionNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.isMethod = source.isMethod; this.useKeywords = source.useKeywords; - + this.eval( source.src, source.includes, source.extensions, source.keywords ); if ( source.type !== undefined ) this.type = source.type; - + }; FunctionNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/core/InputNode.js b/examples/js/nodes/core/InputNode.js index 3ed93ae6e4209507f94f7aa66fd5df1e8d672fb5..ce635b65b9f6ad5a5720eec0800f4b42adcb8fbd 100644 --- a/examples/js/nodes/core/InputNode.js +++ b/examples/js/nodes/core/InputNode.js @@ -13,7 +13,7 @@ function InputNode( type, params ) { this.readonly = false; -}; +} InputNode.prototype = Object.create( TempNode.prototype ); InputNode.prototype.constructor = InputNode; @@ -25,17 +25,17 @@ InputNode.prototype.isReadonly = function ( builder ) { }; InputNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + if ( source.readonly !== undefined ) this.readonly = source.readonly; - + }; InputNode.prototype.createJSONNode = function ( meta ) { var data = TempNode.prototype.createJSONNode.call( this, meta ); - + if ( this.readonly === true ) data.readonly = this.readonly; return data; diff --git a/examples/js/nodes/core/GLNode.js b/examples/js/nodes/core/Node.js similarity index 80% rename from examples/js/nodes/core/GLNode.js rename to examples/js/nodes/core/Node.js index 2edd3eaeb4fcaa777c471b72141f2e724333fd08..f52dd9e04d701da3bc8cf9b4b99bdcf9f95edc61 100644 --- a/examples/js/nodes/core/GLNode.js +++ b/examples/js/nodes/core/Node.js @@ -2,7 +2,7 @@ * @author sunag / http://www.sunag.com.br/ */ -function GLNode( type ) { +function Node( type ) { this.uuid = THREE.Math.generateUUID(); @@ -12,31 +12,31 @@ function GLNode( type ) { this.userData = {}; -}; +} + +Node.prototype = { -GLNode.prototype = { + constructor: Node, - constructor: GLNode, - isNode: true, - + parse: function ( builder, settings ) { settings = settings || {}; builder.parsing = true; - this.build( builder.addCache( settings.cache, settings.requires ).addSlot( settings.slot ), 'v4' ); + this.build( builder.addFlow( settings.slot, settings.cache, settings.context ), 'v4' ); - builder.clearVertexNodeCode() + builder.clearVertexNodeCode(); builder.clearFragmentNodeCode(); - builder.removeCache().removeSlot(); + builder.removeFlow(); builder.parsing = false; }, - + parseAndBuildCode: function ( builder, output, settings ) { settings = settings || {}; @@ -44,21 +44,21 @@ GLNode.prototype = { this.parse( builder, settings ); return this.buildCode( builder, output, settings ); - + }, - + buildCode: function ( builder, output, settings ) { settings = settings || {}; - var data = { result: this.build( builder.addCache( settings.cache, settings.context ).addSlot( settings.slot ), output ) }; + var data = { result: this.build( builder.addFlow( settings.slot, settings.cache, settings.context ), output ) }; data.code = builder.clearNodeCode(); - builder.removeCache().removeSlot(); + builder.removeFlow(); return data; - + }, build: function ( builder, output, uuid ) { @@ -67,7 +67,11 @@ GLNode.prototype = { var data = builder.getNodeData( uuid || this ); - if ( builder.parsing ) this.appendDepsNode( builder, data, output ); + if ( builder.parsing ) { + + this.appendDepsNode( builder, data, output ); + + } if ( builder.nodes.indexOf( this ) === - 1 ) { @@ -82,9 +86,9 @@ GLNode.prototype = { } return this.generate( builder, output, uuid ); - + }, - + appendDepsNode: function ( builder, data, output ) { data.deps = ( data.deps || 0 ) + 1; @@ -97,29 +101,29 @@ GLNode.prototype = { data.output = output; } - + }, - - setName: function( name ) { - + + setName: function ( name ) { + this.name = name; - + return this; - + }, - - getName: function( builder ) { - + + getName: function ( builder ) { + return this.name; - + }, - + getType: function ( builder, output ) { return output === 'sampler2D' || output === 'samplerCube' ? output : this.type; - + }, - + getJSONNode: function ( meta ) { var isRootObject = ( meta === undefined || typeof meta === 'string' ); @@ -129,17 +133,17 @@ GLNode.prototype = { return meta.nodes[ this.uuid ]; } - + }, - + copy: function ( source ) { if ( source.name !== undefined ) this.name = source.name; - + if ( source.userData !== undefined ) this.userData = JSON.parse( JSON.stringify( source.userData ) ); - + }, - + createJSONNode: function ( meta ) { var isRootObject = ( meta === undefined || typeof meta === 'string' ); @@ -162,15 +166,15 @@ GLNode.prototype = { } return data; - + }, - + toJSON: function ( meta ) { return this.getJSONNode( meta ) || this.createJSONNode( meta ); - + } - + }; -export { GLNode }; +export { Node }; diff --git a/examples/js/nodes/core/NodeBuilder.js b/examples/js/nodes/core/NodeBuilder.js index aa08fe1ff8a8f9b6b561b62a296e4248c3b20d2c..1277ecdba0ce25d7c3ef956d385a4a881c9590ae 100644 --- a/examples/js/nodes/core/NodeBuilder.js +++ b/examples/js/nodes/core/NodeBuilder.js @@ -37,16 +37,17 @@ var elements = NodeUtils.elements, m3: 'mat3', m4: 'mat4' }; - + function NodeBuilder() { - this.caches = []; this.slots = []; + this.caches = []; + this.contexts = []; this.keywords = {}; - + this.nodeData = {}; - + this.requires = { uv: [], color: [], @@ -59,11 +60,11 @@ function NodeBuilder() { functions: [], structs: [] }; - + this.attributes = {}; - + this.prefixCode = [ - "#ifdef GL_EXT_shader_texture_lod", + "#ifdef TEXTURE_LOD_EXT", " #define texCube(a, b) textureCube(a, b)", " #define texCubeBias(a, b, c) textureCubeLodEXT(a, b, c)", @@ -81,35 +82,36 @@ function NodeBuilder() { "#endif", - "#include " + "#include ", + "#include " ].join( "\n" ); - + this.parsCode = { vertex: '', fragment: '' }; - + this.code = { vertex: '', fragment: '' }; - + this.nodeCode = { vertex: '', fragment: '' }; - + this.resultCode = { vertex: '', fragment: '' }; - + this.finalCode = { vertex: '', fragment: '' }; - + this.inputs = { uniforms: { list: [], @@ -122,45 +124,43 @@ function NodeBuilder() { fragment: [] } }; - + // send to material - + this.defines = {}; - + this.uniforms = {}; - + this.extensions = {}; - + this.updaters = []; - + this.nodes = []; - + // -- - + this.parsing = false; this.optimize = true; - this.update(); - -}; +} NodeBuilder.prototype = { constructor: NodeBuilder, - build: function( vertex, fragment ) { - + build: function ( vertex, fragment ) { + this.buildShader( 'vertex', vertex ); this.buildShader( 'fragment', fragment ); - + if ( this.requires.uv[ 0 ] ) { this.addVaryCode( 'varying vec2 vUv;' ); - + this.addVertexFinalCode( 'vUv = uv;' ); } - + if ( this.requires.uv[ 1 ] ) { this.addVaryCode( 'varying vec2 vUv2;' ); @@ -169,7 +169,7 @@ NodeBuilder.prototype = { this.addVertexFinalCode( 'vUv2 = uv2;' ); } - + if ( this.requires.color[ 0 ] ) { this.addVaryCode( 'varying vec4 vColor;' ); @@ -178,7 +178,7 @@ NodeBuilder.prototype = { this.addVertexFinalCode( 'vColor = color;' ); } - + if ( this.requires.color[ 1 ] ) { this.addVaryCode( 'varying vec4 vColor2;' ); @@ -187,7 +187,7 @@ NodeBuilder.prototype = { this.addVertexFinalCode( 'vColor2 = color2;' ); } - + if ( this.requires.position ) { this.addVaryCode( 'varying vec3 vPosition;' ); @@ -195,15 +195,15 @@ NodeBuilder.prototype = { this.addVertexFinalCode( 'vPosition = transformed;' ); } - + if ( this.requires.worldPosition ) { this.addVaryCode( 'varying vec3 vWPosition;' ); - + this.addVertexFinalCode( 'vWPosition = ( modelMatrix * vec4( transformed, 1.0 ) ).xyz;' ); } - + if ( this.requires.normal ) { this.addVaryCode( 'varying vec3 vObjectNormal;' ); @@ -211,7 +211,7 @@ NodeBuilder.prototype = { this.addVertexFinalCode( 'vObjectNormal = normal;' ); } - + if ( this.requires.worldNormal ) { this.addVaryCode( 'varying vec3 vWNormal;' ); @@ -219,67 +219,98 @@ NodeBuilder.prototype = { this.addVertexFinalCode( 'vWNormal = ( modelMatrix * vec4( objectNormal, 0.0 ) ).xyz;' ); } - + return this; - + }, - - buildShader: function( shader, node ) { - - this.resultCode[shader] = node.build( this.setShader( shader ), 'v4' ); - + + buildShader: function ( shader, node ) { + + this.resultCode[ shader ] = node.build( this.setShader( shader ), 'v4' ); + }, - - setMaterial: function( material, renderer ) { - + + setMaterial: function ( material, renderer ) { + this.material = material; this.renderer = renderer; - + this.requires.lights = material.lights; this.requires.fog = material.fog; - + + this.mergeDefines( material.defines ); + return this; - + }, - - addCache: function ( name, context ) { - this.caches.push( { - name: name || '', - context: context || {} - } ); + addFlow: function ( slot, cache, context ) { - return this.update(); + return this.addSlot( slot ).addCache( cache ).addContext( context ); + + }, + + removeFlow: function () { + + return this.removeSlot().removeCache().removeContext(); + + }, + + addCache: function ( name ) { + + this.cache = name || ''; + this.caches.push( this.cache ); + + return this; }, removeCache: function () { this.caches.pop(); + this.cache = this.caches[ this.caches.length - 1 ] || ''; + + return this; + + }, + + addContext: function ( context ) { + + this.context = Object.assign( {}, this.context, context ); + this.contexts.push( this.context ); + + return this; + + }, - return this.update(); + removeContext: function () { + + this.contexts.pop(); + this.context = this.contexts[ this.contexts.length - 1 ] || {}; + + return this; }, addSlot: function ( name ) { - this.slots.push( { - name: name || '' - } ); + this.slot = name || ''; + this.slots.push( this.slot ); - return this.update(); + return this; }, removeSlot: function () { this.slots.pop(); + this.slot = this.slots[ this.slots.length - 1 ] || ''; - return this.update(); + return this; }, - + addVertexCode: function ( code ) { this.addCode( code, 'vertex' ); @@ -291,14 +322,14 @@ NodeBuilder.prototype = { this.addCode( code, 'fragment' ); }, - + addCode: function ( code, shader ) { - this.code[shader || this.shader] += code + '\n'; + this.code[ shader || this.shader ] += code + '\n'; }, - - + + addVertexNodeCode: function ( code ) { this.addNodeCode( code, 'vertex' ); @@ -310,37 +341,37 @@ NodeBuilder.prototype = { this.addNodeCode( code, 'fragment' ); }, - + addNodeCode: function ( code, shader ) { - this.nodeCode[shader || this.shader] += code + '\n'; + this.nodeCode[ shader || this.shader ] += code + '\n'; }, - + clearNodeCode: function ( shader ) { shader = shader || this.shader; - - var code = this.nodeCode[shader]; - - this.nodeCode[shader] = ''; + + var code = this.nodeCode[ shader ]; + + this.nodeCode[ shader ] = ''; return code; - + }, - - clearVertexNodeCode: function ( ) { + + clearVertexNodeCode: function ( ) { return this.clearNodeCode( 'vertex' ); }, - - clearFragmentNodeCode: function ( ) { + + clearFragmentNodeCode: function ( ) { return this.clearNodeCode( 'fragment' ); }, - + addVertexFinalCode: function ( code ) { this.addFinalCode( code, 'vertex' ); @@ -352,79 +383,50 @@ NodeBuilder.prototype = { this.addFinalCode( code, 'fragment' ); }, - + addFinalCode: function ( code, shader ) { - this.finalCode[shader || this.shader] += code + '\n'; + this.finalCode[ shader || this.shader ] += code + '\n'; }, - - + + addVertexParsCode: function ( code ) { this.addParsCode( code, 'vertex' ); }, - + addFragmentParsCode: function ( code ) { this.addParsCode( code, 'fragment' ); }, - + addParsCode: function ( code, shader ) { - this.parsCode[shader || this.shader] += code + '\n'; + this.parsCode[ shader || this.shader ] += code + '\n'; }, - - + + addVaryCode: function ( code ) { this.addVertexParsCode( code ); this.addFragmentParsCode( code ); }, - - - isCache: function ( name ) { - var i = this.caches.length; - while ( i -- ) { - - if ( this.caches[ i ].name === name ) return true; - - } + isCache: function ( name ) { - return false; + return this.caches.indexOf( name ) !== - 1; }, isSlot: function ( name ) { - var i = this.slots.length; - - while ( i -- ) { - - if ( this.slots[ i ].name === name ) return true; - - } - - return false; - - }, - - update: function () { - - var cache = this.caches[ this.caches.length - 1 ]; - var slot = this.slots[ this.slots.length - 1 ]; - - this.slot = slot ? slot.name : ''; - this.cache = cache ? cache.name : ''; - this.context = cache ? cache.context : {}; - - return this; + return this.slots.indexOf( name ) !== - 1; }, @@ -433,7 +435,7 @@ NodeBuilder.prototype = { this.defines[ name ] = value === undefined ? 1 : value; }, - + isDefined: function ( name ) { return this.defines[ name ] !== undefined; @@ -443,8 +445,8 @@ NodeBuilder.prototype = { getVar: function ( uuid, type, ns, shader ) { shader = shader || 'varying'; - - var vars = this.getVars(shader), + + var vars = this.getVars( shader ), data = vars[ uuid ]; if ( ! data ) { @@ -462,13 +464,13 @@ NodeBuilder.prototype = { return data; }, - + getTempVar: function ( uuid, type, ns ) { return this.getVar( uuid, type, ns, this.shader ); }, - + getAttribute: function ( name, type ) { if ( ! this.attributes[ name ] ) { @@ -485,45 +487,45 @@ NodeBuilder.prototype = { return this.attributes[ name ]; }, - - getCode: function( shader ) { - + + getCode: function ( shader ) { + return [ this.prefixCode, this.parsCode[ shader ], - this.getVarListCode( this.getVars('varying'), 'varying' ), - this.getVarListCode( this.inputs.uniforms[shader], 'uniform' ), + this.getVarListCode( this.getVars( 'varying' ), 'varying' ), + this.getVarListCode( this.inputs.uniforms[ shader ], 'uniform' ), this.getIncludesCode( 'consts', shader ), this.getIncludesCode( 'structs', shader ), this.getIncludesCode( 'functions', shader ), 'void main() {', - this.getVarListCode( this.getVars(shader) ), - this.code[ shader ], - this.resultCode[ shader ], - this.finalCode[ shader ], + this.getVarListCode( this.getVars( shader ) ), + this.code[ shader ], + this.resultCode[ shader ], + this.finalCode[ shader ], '}' ].join( "\n" ); - + }, - + getVarListCode: function ( vars, prefix ) { prefix = prefix || ''; - + var code = ''; for ( var i = 0, l = vars.length; i < l; ++ i ) { - var nVar = vars[i], + var nVar = vars[ i ], type = nVar.type, name = nVar.name; - + var formatType = this.getFormatByType( type ); if ( formatType === undefined ) { - + throw new Error( "Node pars " + formatType + " not found." ); - + } code += prefix + ' ' + formatType + ' ' + name + ';\n'; @@ -533,21 +535,21 @@ NodeBuilder.prototype = { return code; }, - + getVars: function ( shader ) { return this.inputs.vars[ shader || this.shader ]; }, - + getNodeData: function ( node ) { var uuid = node.isNode ? node.uuid : node; - + return this.nodeData[ uuid ] = this.nodeData[ uuid ] || {}; }, - + createUniform: function ( shader, type, node, ns, needsUpdate ) { var uniforms = this.inputs.uniforms, @@ -555,40 +557,47 @@ NodeBuilder.prototype = { var uniform = new NodeUniform( { type: type, - name: ns ? ns : 'nVu' + index + '_' + THREE.Math.generateUUID().substr(0, 8), + name: ns ? ns : 'nVu' + index, node: node, needsUpdate: needsUpdate } ); uniforms.list.push( uniform ); - uniforms[shader].push( uniform ); - uniforms[shader][ uniform.name ] = uniform; - + uniforms[ shader ].push( uniform ); + uniforms[ shader ][ uniform.name ] = uniform; + this.uniforms[ uniform.name ] = uniform; - + return uniform; }, - + createVertexUniform: function ( type, node, ns, needsUpdate ) { return this.createUniform( 'vertex', type, node, ns, needsUpdate ); }, - + createFragmentUniform: function ( type, node, ns, needsUpdate ) { return this.createUniform( 'fragment', type, node, ns, needsUpdate ); }, - + include: function ( node, parent, source ) { var includesStruct; node = typeof node === 'string' ? NodeLib.get( node ) : node; + if ( this.context.include === false ) { + + return node.name; + + } + + if ( node instanceof FunctionNode ) { includesStruct = this.includes.functions; @@ -596,17 +605,17 @@ NodeBuilder.prototype = { } else if ( node instanceof ConstNode ) { includesStruct = this.includes.consts; - + } else if ( node instanceof StructNode ) { includesStruct = this.includes.structs; } - + var includes = includesStruct[ this.shader ] = includesStruct[ this.shader ] || []; - if (node) { - + if ( node ) { + var included = includes[ node.name ]; if ( ! included ) { @@ -645,13 +654,13 @@ NodeBuilder.prototype = { included.src = source; } - + return node.name; - + } else { - - throw new Error("Include not found."); - + + throw new Error( "Include not found." ); + } }, @@ -661,7 +670,7 @@ NodeBuilder.prototype = { return color.replace( 'r', 'x' ).replace( 'g', 'y' ).replace( 'b', 'z' ).replace( 'a', 'w' ); }, - + colorToVector: function ( color ) { return color.replace( /c/g, 'v3' ); @@ -670,10 +679,10 @@ NodeBuilder.prototype = { getIncludes: function ( type, shader ) { - return this.includes[type][shader || this.shader]; + return this.includes[ type ][ shader || this.shader ]; }, - + getIncludesCode: function () { function sortByPosition( a, b ) { @@ -685,10 +694,10 @@ NodeBuilder.prototype = { return function getIncludesCode( type, shader ) { var includes = this.getIncludes( type, shader ); - + if ( ! includes ) return ''; - var code = '', + var code = '', includes = includes.sort( sortByPosition ); for ( var i = 0; i < includes.length; i ++ ) { @@ -702,7 +711,7 @@ NodeBuilder.prototype = { }; }(), - + getConstructorFromLength: function ( len ) { return constructors[ len - 1 ]; @@ -718,7 +727,7 @@ NodeBuilder.prototype = { getTypeLength: function ( type ) { if ( type === 'f' ) return 1; - + return parseInt( this.colorToVector( type ).substr( 1 ) ); }, @@ -730,109 +739,109 @@ NodeBuilder.prototype = { return 'v' + len; }, - - findNode: function() { - - for(var i = 0; i < arguments.length; i++) { - - var nodeCandidate = arguments[i]; - - if (nodeCandidate !== undefined && nodeCandidate.isNode) { - + + findNode: function () { + + for ( var i = 0; i < arguments.length; i ++ ) { + + var nodeCandidate = arguments[ i ]; + + if ( nodeCandidate !== undefined && nodeCandidate.isNode ) { + return nodeCandidate; - + } - + } - - }, - - resolve: function() { - - for(var i = 0; i < arguments.length; i++) { - - var nodeCandidate = arguments[i]; - - if (nodeCandidate !== undefined) { - - if (nodeCandidate.isNode) { - + + }, + + resolve: function () { + + for ( var i = 0; i < arguments.length; i ++ ) { + + var nodeCandidate = arguments[ i ]; + + if ( nodeCandidate !== undefined ) { + + if ( nodeCandidate.isNode ) { + return nodeCandidate; - - } else if (nodeCandidate.isTexture) { - - switch( nodeCandidate.mapping ) { - + + } else if ( nodeCandidate.isTexture ) { + + switch ( nodeCandidate.mapping ) { + case THREE.CubeReflectionMapping: case THREE.CubeRefractionMapping: return new CubeTextureNode( nodeCandidate ); break; - + case THREE.CubeUVReflectionMapping: case THREE.CubeUVRefractionMapping: return new TextureCubeNode( new TextureNode( nodeCandidate ) ); break; - + default: - + return new TextureNode( nodeCandidate ); - + } - - } else if (nodeCandidate.isVector2) { - + + } else if ( nodeCandidate.isVector2 ) { + return new Vector2Node( nodeCandidate ); - - } else if (nodeCandidate.isVector3) { - + + } else if ( nodeCandidate.isVector3 ) { + return new Vector3Node( nodeCandidate ); - - } else if (nodeCandidate.isVector4) { - + + } else if ( nodeCandidate.isVector4 ) { + return new Vector4Node( nodeCandidate ); - + } - + } - + } - + }, format: function ( code, from, to ) { - var typeToType = this.colorToVector( to + ' = ' + from ); + var typeToType = this.colorToVector( to + ' <- ' + from ); switch ( typeToType ) { - case 'f = v2': return code + '.x'; - case 'f = v3': return code + '.x'; - case 'f = v4': return code + '.x'; - case 'f = i': return 'float( ' + code + ' )'; + case 'f <- v2' : return code + '.x'; + case 'f <- v3' : return code + '.x'; + case 'f <- v4' : return code + '.x'; + case 'f <- i' : return 'float( ' + code + ' )'; - case 'v2 = f': return 'vec2( ' + code + ' )'; - case 'v2 = v3': return code + '.xy'; - case 'v2 = v4': return code + '.xy'; - case 'v2 = i': return 'vec2( float( ' + code + ' ) )'; + case 'v2 <- f' : return 'vec2( ' + code + ' )'; + case 'v2 <- v3': return code + '.xy'; + case 'v2 <- v4': return code + '.xy'; + case 'v2 <- i' : return 'vec2( float( ' + code + ' ) )'; - case 'v3 = f': return 'vec3( ' + code + ' )'; - case 'v3 = v2': return 'vec3( ' + code + ', 0.0 )'; - case 'v3 = v4': return code + '.xyz'; - case 'v3 = i': return 'vec2( float( ' + code + ' ) )'; + case 'v3 <- f' : return 'vec3( ' + code + ' )'; + case 'v3 <- v2': return 'vec3( ' + code + ', 0.0 )'; + case 'v3 <- v4': return code + '.xyz'; + case 'v3 <- i' : return 'vec2( float( ' + code + ' ) )'; - case 'v4 = f': return 'vec4( ' + code + ' )'; - case 'v4 = v2': return 'vec4( ' + code + ', 0.0, 1.0 )'; - case 'v4 = v3': return 'vec4( ' + code + ', 1.0 )'; - case 'v4 = i': return 'vec4( float( ' + code + ' ) )'; + case 'v4 <- f' : return 'vec4( ' + code + ' )'; + case 'v4 <- v2': return 'vec4( ' + code + ', 0.0, 1.0 )'; + case 'v4 <- v3': return 'vec4( ' + code + ', 1.0 )'; + case 'v4 <- i' : return 'vec4( float( ' + code + ' ) )'; - case 'i = f': return 'int( ' + code + ' )'; - case 'i = v2': return 'int( ' + code + '.x )'; - case 'i = v3': return 'int( ' + code + '.x )'; - case 'i = v4': return 'int( ' + code + '.x )'; + case 'i <- f' : return 'int( ' + code + ' )'; + case 'i <- v2' : return 'int( ' + code + '.x )'; + case 'i <- v3' : return 'int( ' + code + '.x )'; + case 'i <- v4' : return 'int( ' + code + '.x )'; } @@ -845,7 +854,7 @@ NodeBuilder.prototype = { return convertFormatToType[ format ] || format; }, - + getFormatByType: function ( type ) { return convertTypeToFormat[ type ] || type; @@ -887,93 +896,35 @@ NodeBuilder.prototype = { return this; }, - - mergeUniform: function ( uniforms ) { - - for ( var name in uniforms ) { - - this.uniforms[ name ] = uniforms[ name ]; - - } - - }, - - getTexelDecodingFunctionFromTexture: function( code, texture ) { - - var gammaOverrideLinear = this.getTextureEncodingFromMap( texture, this.context.gamma && ( this.renderer ? this.renderer.gammaInput : false ) ) - - return this.getTexelDecodingFunction( code, gammaOverrideLinear ); - - }, - - getTexelDecodingFunction: function( value, encoding ) { - - var components = this.getEncodingComponents( encoding ); - return components[ 0 ] + 'ToLinear' + components[ 1 ].replace( 'value', value ); + mergeDefines: function ( defines ) { - }, + for ( var name in defines ) { - getTexelEncodingFunction: function( value, encoding ) { + this.defines[ name ] = defines[ name ]; - var components = this.getEncodingComponents( encoding ); + } - return 'LinearTo' + components[ 0 ] + components[ 1 ].replace( 'value', value ); + return this.defines; }, - getEncodingComponents: function( encoding ) { + mergeUniform: function ( uniforms ) { - switch ( encoding ) { + for ( var name in uniforms ) { - case THREE.LinearEncoding: - return [ 'Linear', '( value )' ]; - case THREE.sRGBEncoding: - return [ 'sRGB', '( value )' ]; - case THREE.RGBEEncoding: - return [ 'RGBE', '( value )' ]; - case THREE.RGBM7Encoding: - return [ 'RGBM', '( value, 7.0 )' ]; - case THREE.RGBM16Encoding: - return [ 'RGBM', '( value, 16.0 )' ]; - case THREE.RGBDEncoding: - return [ 'RGBD', '( value, 256.0 )' ]; - case THREE.GammaEncoding: - return [ 'Gamma', '( value, float( GAMMA_FACTOR ) )' ]; - default: - throw new Error( 'unsupported encoding: ' + encoding ); + this.uniforms[ name ] = uniforms[ name ]; } - }, - - getEncodingComponents: function( encoding ) { - - switch ( encoding ) { - - case THREE.LinearEncoding: - return [ 'Linear', '( value )' ]; - case THREE.sRGBEncoding: - return [ 'sRGB', '( value )' ]; - case THREE.RGBEEncoding: - return [ 'RGBE', '( value )' ]; - case THREE.RGBM7Encoding: - return [ 'RGBM', '( value, 7.0 )' ]; - case THREE.RGBM16Encoding: - return [ 'RGBM', '( value, 16.0 )' ]; - case THREE.RGBDEncoding: - return [ 'RGBD', '( value, 256.0 )' ]; - case THREE.GammaEncoding: - return [ 'Gamma', '( value, float( GAMMA_FACTOR ) )' ]; - default: - throw new Error( 'unsupported encoding: ' + encoding ); - - } + return this.uniforms; }, - + getTextureEncodingFromMap: function ( map, gammaOverrideLinear ) { + gammaOverrideLinear = gammaOverrideLinear !== undefined ? gammaOverrideLinear : this.context.gamma && ( this.renderer ? this.renderer.gammaInput : false ); + var encoding; if ( ! map ) { diff --git a/examples/js/nodes/core/NodeFrame.js b/examples/js/nodes/core/NodeFrame.js index ace76d6924b997ac12e0bfe207cdf89c0e1ce44c..c0e0433d51a5cd68a30e5c93de8961c0303bd73d 100644 --- a/examples/js/nodes/core/NodeFrame.js +++ b/examples/js/nodes/core/NodeFrame.js @@ -6,9 +6,9 @@ function NodeFrame( time ) { this.time = time !== undefined ? time : 0; - this.frameId = 0; + this.id = 0; -}; +} NodeFrame.prototype = { @@ -16,7 +16,7 @@ NodeFrame.prototype = { update: function ( delta ) { - ++this.frameId; + ++ this.id; this.time += delta; this.delta = delta; @@ -24,19 +24,35 @@ NodeFrame.prototype = { return this; }, - + + setRenderer: function ( renderer ) { + + this.renderer = renderer; + + return this; + + }, + + setRenderTexture: function ( renderTexture ) { + + this.renderTexture = renderTexture; + + return this; + + }, + updateNode: function ( node ) { - if ( node.frameId === this.frameId ) return this; + if ( node.frameId === this.id ) return this; node.updateFrame( this ); - node.frameId = this.frameId; + node.frameId = this.id; return this; } - + }; export { NodeFrame }; diff --git a/examples/js/nodes/core/NodeUniform.js b/examples/js/nodes/core/NodeUniform.js index 66c8fb434d9b23269aa0af1c41468479bd9f3aa5..3ba0bb1837bda29feccf2c1c4ffb6c135a31fc8f 100644 --- a/examples/js/nodes/core/NodeUniform.js +++ b/examples/js/nodes/core/NodeUniform.js @@ -11,26 +11,26 @@ function NodeUniform( params ) { this.node = params.node; this.needsUpdate = params.needsUpdate; -}; +} Object.defineProperties( NodeUniform.prototype, { - + value: { - + get: function () { return this.node.value; }, - + set: function ( val ) { this.node.value = val; } - + } - + } ); export { NodeUniform }; diff --git a/examples/js/nodes/core/NodeUtils.js b/examples/js/nodes/core/NodeUtils.js index 2149cc172368e32bfadba55dea98efb09e0d582f..60b3ec138f3de98d9e2ad164483ba636a8b94907 100644 --- a/examples/js/nodes/core/NodeUtils.js +++ b/examples/js/nodes/core/NodeUtils.js @@ -13,37 +13,37 @@ var NodeUtils = { if ( subProperty ) { return { - + get: function () { return this[ proxy ][ property ][ subProperty ]; }, - + set: function ( val ) { this[ proxy ][ property ][ subProperty ] = val; } - + }; } else { return { - + get: function () { return this[ proxy ][ property ]; }, - + set: function ( val ) { this[ proxy ][ property ] = val; } - + }; } @@ -57,8 +57,8 @@ var NodeUtils = { for ( var i = 0; i < list.length; ++ i ) { var data = list[ i ].split( "." ), - property = data[0], - subProperty = data[1]; + property = data[ 0 ], + subProperty = data[ 1 ]; shortcuts[ property ] = applyShortcut( proxy, property, subProperty ); @@ -69,7 +69,7 @@ var NodeUtils = { }; }() - + }; export { NodeUtils }; diff --git a/examples/js/nodes/core/StructNode.js b/examples/js/nodes/core/StructNode.js index 79f209bff93e2021d28dc8e72f8d8ce3143dff1b..9888de356b9f13a454b2eba6880a396a2f10048f 100644 --- a/examples/js/nodes/core/StructNode.js +++ b/examples/js/nodes/core/StructNode.js @@ -3,18 +3,17 @@ */ import { TempNode } from './TempNode.js'; -import { FunctionNode } from './FunctionNode.js'; + +var declarationRegexp = /^struct\s*([a-z_0-9]+)\s*{\s*((.|\n)*?)}/img, + propertiesRegexp = /\s*(\w*?)\s*(\w*?)(\=|\;)/img; function StructNode( src ) { - TempNode.call( this); + TempNode.call( this ); this.eval( src ); -}; - -StructNode.rDeclaration = /^struct\s*([a-z_0-9]+)\s*{\s*((.|\n)*?)}/img; -StructNode.rProperties = /\s*(\w*?)\s*(\w*?)(\=|\;)/img; +} StructNode.prototype = Object.create( TempNode.prototype ); StructNode.prototype.constructor = StructNode; @@ -32,9 +31,12 @@ StructNode.prototype.getInputByName = function ( name ) { while ( i -- ) { - if ( this.inputs[ i ].name === name ) + if ( this.inputs[ i ].name === name ) { + return this.inputs[ i ]; + } + } }; @@ -47,7 +49,7 @@ StructNode.prototype.generate = function ( builder, output ) { } else { - return builder.format( "(" + src + ")", this.getType( builder ), output ); + return builder.format( '( ' + src + ' )', this.getType( builder ), output ); } @@ -56,34 +58,32 @@ StructNode.prototype.generate = function ( builder, output ) { StructNode.prototype.eval = function ( src ) { this.src = src || ''; - + this.inputs = []; - - var declaration = StructNode.rDeclaration.exec( this.src ); - - if (declaration) { - - var properties = declaration[2], matchType, matchName; - - while ( matchType = FunctionNode.rProperties.exec( properties ) ) { - - matchName = FunctionNode.rProperties.exec( properties )[0]; - + + var declaration = declarationRegexp.exec( this.src ); + + if ( declaration ) { + + var properties = declaration[ 2 ], match; + + while ( match = propertiesRegexp.exec( properties ) ) { + this.inputs.push( { - name: matchName, - type: matchType + type: match[ 1 ], + name: match[ 2 ] } ); - + } - - this.name = declaration[1]; + + this.name = declaration[ 1 ]; } else { - + this.name = ''; - + } - + this.type = this.name; }; diff --git a/examples/js/nodes/core/TempNode.js b/examples/js/nodes/core/TempNode.js index a214e52249c9d93c60f3fa8baa9cc95603b40166..ead9f8022a86fd0dcbb6dbdc74feabee2fff4a79 100644 --- a/examples/js/nodes/core/TempNode.js +++ b/examples/js/nodes/core/TempNode.js @@ -3,20 +3,20 @@ * @author sunag / http://www.sunag.com.br/ */ -import { GLNode } from './GLNode.js'; +import { Node } from './Node.js'; function TempNode( type, params ) { - GLNode.call( this, type ); + Node.call( this, type ); params = params || {}; this.shared = params.shared !== undefined ? params.shared : true; this.unique = params.unique !== undefined ? params.unique : false; -}; +} -TempNode.prototype = Object.create( GLNode.prototype ); +TempNode.prototype = Object.create( Node.prototype ); TempNode.prototype.constructor = TempNode; TempNode.prototype.build = function ( builder, output, uuid, ns ) { @@ -35,36 +35,36 @@ TempNode.prototype.build = function ( builder, output, uuid, ns ) { uuid = builder.getUuid( uuid || this.getUuid(), ! isUnique ); - var data = builder.getNodeData( uuid ); + var data = builder.getNodeData( uuid ), + type = data.output || this.getType( builder ); if ( builder.parsing ) { - if ( data.deps || 0 > 0 ) { + if ( ( data.deps || 0 ) > 0 ) { this.appendDepsNode( builder, data, output ); - return this.generate( builder, type, uuid ); + return this.generate( builder, output, uuid ); } - return GLNode.prototype.build.call( this, builder, output, uuid ); + return Node.prototype.build.call( this, builder, output, uuid ); } else if ( isUnique ) { - data.name = data.name || GLNode.prototype.build.call( this, builder, output, uuid ); + data.name = data.name || Node.prototype.build.call( this, builder, output, uuid ); return data.name; - } else if ( ! builder.optimize || data.deps == 1 ) { + } else if ( ! this.isShared( builder, type ) || ( ! builder.optimize || data.deps == 1 ) ) { - return GLNode.prototype.build.call( this, builder, output, uuid ); + return Node.prototype.build.call( this, builder, output, uuid ); } uuid = this.getUuid( false ); - var name = this.getTemp( builder, uuid ), - type = data.output || this.getType( builder ); + var name = this.getTemp( builder, uuid ); if ( name ) { @@ -84,7 +84,7 @@ TempNode.prototype.build = function ( builder, output, uuid, ns ) { } - return GLNode.prototype.build.call( this, builder, output, uuid ); + return Node.prototype.build.call( this, builder, output, uuid ); }; @@ -114,10 +114,10 @@ TempNode.prototype.getTemp = function ( builder, uuid ) { uuid = uuid || this.uuid; - var tempVar = builder.getVars()[uuid] - + var tempVar = builder.getVars()[ uuid ]; + return tempVar ? tempVar.name : undefined; - + }; TempNode.prototype.generate = function ( builder, output, uuid, type, ns ) { diff --git a/examples/js/nodes/core/VarNode.js b/examples/js/nodes/core/VarNode.js index fac826beef79aa5ec6ca3c6338427b182e115adf..9e9e78ee8c2cd00d327729a385d119a9f943dde1 100644 --- a/examples/js/nodes/core/VarNode.js +++ b/examples/js/nodes/core/VarNode.js @@ -2,17 +2,17 @@ * @author sunag / http://www.sunag.com.br/ */ -import { GLNode } from './GLNode.js'; +import { Node } from './Node.js'; function VarNode( type, value ) { - GLNode.call( this, type ); - + Node.call( this, type ); + this.value = value; -}; +} -VarNode.prototype = Object.create( GLNode.prototype ); +VarNode.prototype = Object.create( Node.prototype ); VarNode.prototype.constructor = VarNode; VarNode.prototype.nodeType = "Var"; @@ -31,18 +31,18 @@ VarNode.prototype.generate = function ( builder, output ) { builder.addNodeCode( varying.name + ' = ' + this.value.build( builder, this.getType( builder ) ) + ';' ); } - + return builder.format( varying.name, this.getType( builder ), output ); }; VarNode.prototype.copy = function ( source ) { - - GLNode.prototype.copy.call( this, source ); - + + Node.prototype.copy.call( this, source ); + this.type = source.type; this.value = source.value; - + }; VarNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/effects/BlurNode.js b/examples/js/nodes/effects/BlurNode.js index 4c77bcca50909f5a69ffa93b9bcbac0831d52ad5..80c8d4b5769998e3fc631ce1326a0fe6eda1e49d 100644 --- a/examples/js/nodes/effects/BlurNode.js +++ b/examples/js/nodes/effects/BlurNode.js @@ -24,10 +24,10 @@ function BlurNode( value, uv, radius, size ) { this.horizontal = new FloatNode( 1 / 64 ); this.vertical = new FloatNode( 1 / 64 ); -}; +} + +BlurNode.Nodes = ( function () { -BlurNode.Nodes = (function() { - var blurX = new FunctionNode( [ "vec4 blurX( sampler2D texture, vec2 uv, float s ) {", " vec4 sum = vec4( 0.0 );", @@ -40,10 +40,10 @@ BlurNode.Nodes = (function() { " sum += texture2D( texture, vec2( uv.x + 2.0 * s, uv.y ) ) * 0.12245;", " sum += texture2D( texture, vec2( uv.x + 3.0 * s, uv.y ) ) * 0.0918;", " sum += texture2D( texture, vec2( uv.x + 4.0 * s, uv.y ) ) * 0.051;", - " return sum;", + " return sum * .667;", "}" ].join( "\n" ) ); - + var blurY = new FunctionNode( [ "vec4 blurY( sampler2D texture, vec2 uv, float s ) {", " vec4 sum = vec4( 0.0 );", @@ -56,16 +56,16 @@ BlurNode.Nodes = (function() { " sum += texture2D( texture, vec2( uv.x, uv.y + 2.0 * s ) ) * 0.12245;", " sum += texture2D( texture, vec2( uv.x, uv.y + 3.0 * s ) ) * 0.0918;", " sum += texture2D( texture, vec2( uv.x, uv.y + 4.0 * s ) ) * 0.051;", - " return sum;", + " return sum * .667;", "}" ].join( "\n" ) ); - + return { blurX: blurX, blurY: blurY }; - -})(); + +} )(); BlurNode.prototype = Object.create( TempNode.prototype ); @@ -98,7 +98,7 @@ BlurNode.prototype.generate = function ( builder, output ) { var blurX = builder.include( BlurNode.Nodes.blurX ), blurY = builder.include( BlurNode.Nodes.blurY ); - + if ( this.blurX ) { blurCode.push( blurX + '( ' + this.value.build( builder, 'sampler2D' ) + ', ' + this.uv.build( builder, 'v2' ) + ', ' + this.horizontal.build( builder, 'f' ) + ' )' ); @@ -111,7 +111,7 @@ BlurNode.prototype.generate = function ( builder, output ) { } - if ( blurCode.length == 2 ) code = '( ' + blurCode.join( ' + ' ) + '/ 2.0 )'; + if ( blurCode.length == 2 ) code = '( ' + blurCode.join( ' + ' ) + ' / 2.0 )'; else if ( blurCode.length ) code = '( ' + blurCode[ 0 ] + ' )'; else code = 'vec4( 0.0 )'; @@ -128,9 +128,9 @@ BlurNode.prototype.generate = function ( builder, output ) { }; BlurNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.value = source.value; this.uv = source.uv; this.radius = source.radius; @@ -139,7 +139,7 @@ BlurNode.prototype.copy = function ( source ) { this.blurX = source.blurX; this.blurY = source.blurY; - + }; BlurNode.prototype.toJSON = function ( meta ) { @@ -165,4 +165,4 @@ BlurNode.prototype.toJSON = function ( meta ) { }; -export { BlurNode }; \ No newline at end of file +export { BlurNode }; diff --git a/examples/js/nodes/effects/ColorAdjustmentNode.js b/examples/js/nodes/effects/ColorAdjustmentNode.js index 002d648ecf3cad6a0eb8c1900cf3a660f89faaf0..0208192de99e1b44f8ad16fa263807a6a24b0f25 100644 --- a/examples/js/nodes/effects/ColorAdjustmentNode.js +++ b/examples/js/nodes/effects/ColorAdjustmentNode.js @@ -15,58 +15,58 @@ function ColorAdjustmentNode( rgb, adjustment, method ) { this.method = method || ColorAdjustmentNode.SATURATION; -}; +} + +ColorAdjustmentNode.Nodes = ( function () { -ColorAdjustmentNode.Nodes = (function() { - var hue = new FunctionNode( [ "vec3 hue(vec3 rgb, float adjustment) {", - + " const mat3 RGBtoYIQ = mat3(0.299, 0.587, 0.114, 0.595716, -0.274453, -0.321263, 0.211456, -0.522591, 0.311135);", " const mat3 YIQtoRGB = mat3(1.0, 0.9563, 0.6210, 1.0, -0.2721, -0.6474, 1.0, -1.107, 1.7046);", - + " vec3 yiq = RGBtoYIQ * rgb;", - + " float hue = atan(yiq.z, yiq.y) + adjustment;", " float chroma = sqrt(yiq.z * yiq.z + yiq.y * yiq.y);", - + " return YIQtoRGB * vec3(yiq.x, chroma * cos(hue), chroma * sin(hue));", - + "}" ].join( "\n" ) ); - + var saturation = new FunctionNode( [ // Algorithm from Chapter 16 of OpenGL Shading Language "vec3 saturation(vec3 rgb, float adjustment) {", - + " vec3 intensity = vec3( luminance( rgb ) );", - + " return mix( intensity, rgb, adjustment );", - + "}" ].join( "\n" ), [ LuminanceNode.Nodes.luminance ] ); // include LuminanceNode function - + var vibrance = new FunctionNode( [ // Shader by Evan Wallace adapted by @lo-th "vec3 vibrance(vec3 rgb, float adjustment) {", - + " float average = (rgb.r + rgb.g + rgb.b) / 3.0;", - + " float mx = max(rgb.r, max(rgb.g, rgb.b));", " float amt = (mx - average) * (-3.0 * adjustment);", - + " return mix(rgb.rgb, vec3(mx), amt);", - + "}" ].join( "\n" ) ); - + return { hue: hue, saturation: saturation, vibrance: vibrance }; - -})(); + +} )(); ColorAdjustmentNode.SATURATION = 'saturation'; ColorAdjustmentNode.HUE = 'hue'; @@ -99,16 +99,16 @@ ColorAdjustmentNode.prototype.generate = function ( builder, output ) { } - var method = builder.include( ColorAdjustmentNode.Nodes[this.method] ); + var method = builder.include( ColorAdjustmentNode.Nodes[ this.method ] ); return builder.format( method + '( ' + rgb + ', ' + adjustment + ' )', this.getType( builder ), output ); }; ColorAdjustmentNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.rgb = source.rgb; this.adjustment = source.adjustment; this.method = source.method; @@ -133,4 +133,4 @@ ColorAdjustmentNode.prototype.toJSON = function ( meta ) { }; -export { ColorAdjustmentNode }; \ No newline at end of file +export { ColorAdjustmentNode }; diff --git a/examples/js/nodes/effects/LuminanceNode.js b/examples/js/nodes/effects/LuminanceNode.js index 3ddd53213c4029f995391a619d76d972b3ea4491..799a86b5afec37fcee4a1544379ef10074bb452f 100644 --- a/examples/js/nodes/effects/LuminanceNode.js +++ b/examples/js/nodes/effects/LuminanceNode.js @@ -12,18 +12,18 @@ function LuminanceNode( rgb ) { this.rgb = rgb; -}; +} + +LuminanceNode.Nodes = ( function () { -LuminanceNode.Nodes = (function() { - var LUMA = new ConstNode( "vec3 LUMA vec3( 0.2125, 0.7154, 0.0721 )" ); var luminance = new FunctionNode( [ // Algorithm from Chapter 10 of Graphics Shaders "float luminance( vec3 rgb ) {", - + " return dot( rgb, LUMA );", - + "}" ].join( "\n" ), [ LUMA ] ); @@ -31,8 +31,8 @@ LuminanceNode.Nodes = (function() { LUMA: LUMA, luminance: luminance }; - -})(); + +} )(); LuminanceNode.prototype = Object.create( TempNode.prototype ); LuminanceNode.prototype.constructor = LuminanceNode; @@ -47,11 +47,11 @@ LuminanceNode.prototype.generate = function ( builder, output ) { }; LuminanceNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.rgb = source.rgb; - + }; LuminanceNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/inputs/ColorNode.js b/examples/js/nodes/inputs/ColorNode.js index 54de1e09fa5dfe51b00994dded82fa5b5b346825..81413c23aebd4a92e883976e3a14dac7caff899b 100644 --- a/examples/js/nodes/inputs/ColorNode.js +++ b/examples/js/nodes/inputs/ColorNode.js @@ -11,7 +11,7 @@ function ColorNode( color, g, b ) { this.value = color instanceof THREE.Color ? color : new THREE.Color( color || 0, g, b ); -}; +} ColorNode.prototype = Object.create( InputNode.prototype ); ColorNode.prototype.constructor = ColorNode; @@ -26,11 +26,11 @@ ColorNode.prototype.generateReadonly = function ( builder, output, uuid, type, n }; ColorNode.prototype.copy = function ( source ) { - + InputNode.prototype.copy.call( this, source ); - + this.value.copy( source ); - + }; ColorNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/inputs/CubeTextureNode.js b/examples/js/nodes/inputs/CubeTextureNode.js index 9d1f0a54e33ed6170f07f74dc2cd2238cd52fa4e..ad7d2b5c56354762d890f15baa097b4a3d34c2e8 100644 --- a/examples/js/nodes/inputs/CubeTextureNode.js +++ b/examples/js/nodes/inputs/CubeTextureNode.js @@ -4,6 +4,7 @@ import { InputNode } from '../core/InputNode.js'; import { ReflectNode } from '../accessors/ReflectNode.js'; +import { ColorSpaceNode } from '../utils/ColorSpaceNode.js'; function CubeTextureNode( value, uv, bias ) { @@ -13,7 +14,7 @@ function CubeTextureNode( value, uv, bias ) { this.uv = uv || new ReflectNode(); this.bias = bias; -}; +} CubeTextureNode.prototype = Object.create( InputNode.prototype ); CubeTextureNode.prototype.constructor = CubeTextureNode; @@ -48,22 +49,29 @@ CubeTextureNode.prototype.generate = function ( builder, output ) { if ( bias ) code = 'texCubeBias( ' + cubetex + ', ' + uv + ', ' + bias + ' )'; else code = 'texCube( ' + cubetex + ', ' + uv + ' )'; - code = builder.getTexelDecodingFunctionFromTexture( code, this.value ); + // add this context to replace ColorSpaceNode.input to code + + builder.addContext( { input: code, encoding: builder.getTextureEncodingFromMap( this.value ), include: builder.isShader( 'vertex' ) } ); + + this.colorSpace = this.colorSpace || new ColorSpaceNode( this ); + code = this.colorSpace.build( builder, this.type ); + + builder.removeContext(); return builder.format( code, this.type, output ); }; CubeTextureNode.prototype.copy = function ( source ) { - + InputNode.prototype.copy.call( this, source ); - + if ( source.value ) this.value = source.value; this.uv = source.uv; if ( source.bias ) this.bias = source.bias; - + }; CubeTextureNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/inputs/FloatNode.js b/examples/js/nodes/inputs/FloatNode.js index e0d4d2a5af66700fa07b3e891ef9412ab86ab911..604bf170aeabd1996baf9f5a10ce8c4152e39694 100644 --- a/examples/js/nodes/inputs/FloatNode.js +++ b/examples/js/nodes/inputs/FloatNode.js @@ -10,7 +10,7 @@ function FloatNode( value ) { this.value = value || 0; -}; +} FloatNode.prototype = Object.create( InputNode.prototype ); FloatNode.prototype.constructor = FloatNode; @@ -23,11 +23,11 @@ FloatNode.prototype.generateReadonly = function ( builder, output, uuid, type, n }; FloatNode.prototype.copy = function ( source ) { - + InputNode.prototype.copy.call( this, source ); - + this.value = source.value; - + }; FloatNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/inputs/IntNode.js b/examples/js/nodes/inputs/IntNode.js index 39016413b2c4697fac8e3d22825cfa879f912f2b..c35c8a0f40deda488ed7f55c48bab005fb26dc04 100644 --- a/examples/js/nodes/inputs/IntNode.js +++ b/examples/js/nodes/inputs/IntNode.js @@ -10,7 +10,7 @@ function IntNode( value ) { this.value = Math.floor( value || 0 ); -}; +} IntNode.prototype = Object.create( InputNode.prototype ); IntNode.prototype.constructor = IntNode; @@ -23,11 +23,11 @@ IntNode.prototype.generateReadonly = function ( builder, output, uuid, type, ns, }; IntNode.prototype.copy = function ( source ) { - + InputNode.prototype.copy.call( this, source ); - + this.value = source.value; - + }; IntNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/inputs/Matrix3Node.js b/examples/js/nodes/inputs/Matrix3Node.js index 16e147090c6ced31f300e63a0fee2b7c18dceacd..25799d20f9e7d0815b252baf5b72b70fc7efac88 100644 --- a/examples/js/nodes/inputs/Matrix3Node.js +++ b/examples/js/nodes/inputs/Matrix3Node.js @@ -10,7 +10,7 @@ function Matrix3Node( matrix ) { this.value = matrix || new THREE.Matrix3(); -}; +} Matrix3Node.prototype = Object.create( InputNode.prototype ); Matrix3Node.prototype.constructor = Matrix3Node; @@ -19,19 +19,19 @@ Matrix3Node.prototype.nodeType = "Matrix3"; Object.defineProperties( Matrix3Node.prototype, { elements: { - - set: function (val) { + + set: function ( val ) { this.value.elements = val; }, - + get: function () { return this.value.elements; } - + } } ); @@ -44,11 +44,11 @@ Matrix3Node.prototype.generateReadonly = function ( builder, output, uuid, type, Matrix3Node.prototype.copy = function ( source ) { - + InputNode.prototype.copy.call( this, source ); - + this.value.fromArray( source.elements ); - + }; Matrix3Node.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/inputs/Matrix4Node.js b/examples/js/nodes/inputs/Matrix4Node.js index 9bf890fe274e00de7a6dd233d7e3bce02ee650b4..50c0084f996d323c58c2122afe56babff0fc005f 100644 --- a/examples/js/nodes/inputs/Matrix4Node.js +++ b/examples/js/nodes/inputs/Matrix4Node.js @@ -10,7 +10,7 @@ function Matrix4Node( matrix ) { this.value = matrix || new THREE.Matrix4(); -}; +} Matrix4Node.prototype = Object.create( InputNode.prototype ); Matrix4Node.prototype.constructor = Matrix4Node; @@ -19,19 +19,19 @@ Matrix4Node.prototype.nodeType = "Matrix4"; Object.defineProperties( Matrix4Node.prototype, { elements: { - - set: function (val) { + + set: function ( val ) { this.value.elements = val; }, - + get: function () { return this.value.elements; } - + } } ); @@ -43,11 +43,11 @@ Matrix4Node.prototype.generateReadonly = function ( builder, output, uuid, type, }; Matrix4Node.prototype.copy = function ( source ) { - + InputNode.prototype.copy.call( this, source ); - + this.scope.value.fromArray( source.elements ); - + }; Matrix4Node.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/inputs/PropertyNode.js b/examples/js/nodes/inputs/PropertyNode.js index deb5fcab6bcd8408c8daf8b1d0c13d1cfa26043e..b6d92249abfe3ae016c864b88e3ed685f7e27541 100644 --- a/examples/js/nodes/inputs/PropertyNode.js +++ b/examples/js/nodes/inputs/PropertyNode.js @@ -3,15 +3,15 @@ */ import { InputNode } from '../core/InputNode.js'; - + function PropertyNode( object, property, type ) { InputNode.call( this, type ); - + this.object = object; this.property = property; -}; +} PropertyNode.prototype = Object.create( InputNode.prototype ); PropertyNode.prototype.constructor = PropertyNode; @@ -20,19 +20,19 @@ PropertyNode.prototype.nodeType = "Property"; Object.defineProperties( PropertyNode.prototype, { value: { - + get: function () { return this.object[ this.property ]; }, - - set: function ( val ) { - + + set: function ( val ) { + this.object[ this.property ] = val; - + } - + } } ); diff --git a/examples/js/nodes/inputs/RTTNode.js b/examples/js/nodes/inputs/RTTNode.js new file mode 100644 index 0000000000000000000000000000000000000000..0abc03c8b20ae8e704bd8ee5b5c1483aea264142 --- /dev/null +++ b/examples/js/nodes/inputs/RTTNode.js @@ -0,0 +1,143 @@ +/** + * @author sunag / http://www.sunag.com.br/ + */ + +import { NodeMaterial } from '../materials/NodeMaterial.js'; +import { TextureNode } from './TextureNode.js'; + +function RTTNode( width, height, input, options ) { + + options = options || {}; + + this.input = input; + + this.clear = options.clear !== undefined ? options.clear : true; + + this.renderTarget = new THREE.WebGLRenderTarget( width, height, options ); + + this.material = new NodeMaterial(); + + this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); + this.scene = new THREE.Scene(); + + this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), this.material ); + this.quad.frustumCulled = false; // Avoid getting clipped + this.scene.add( this.quad ); + + this.render = true; + + TextureNode.call( this, this.renderTarget.texture ); + +} + +RTTNode.prototype = Object.create( TextureNode.prototype ); +RTTNode.prototype.constructor = RTTNode; +RTTNode.prototype.nodeType = "RTT"; + +RTTNode.prototype.build = function ( builder, output, uuid ) { + + var rttBuilder = new THREE.NodeBuilder(); + rttBuilder.nodes = builder.nodes; + rttBuilder.updaters = builder.updaters; + + this.material.fragment.value = this.input; + this.material.build( { builder: rttBuilder } ); + + return TextureNode.prototype.build.call( this, builder, output, uuid ); + +}; + +RTTNode.prototype.updateFramesaveTo = function ( frame ) { + + this.saveTo.render = false; + + if ( this.saveTo !== this.saveToCurrent ) { + + if ( this.saveToMaterial ) this.saveToMaterial.dispose(); + + var material = new NodeMaterial(); + material.fragment.value = this; + material.build(); + + var scene = new THREE.Scene(); + + var quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), material ); + quad.frustumCulled = false; // Avoid getting clipped + scene.add( quad ); + + this.saveToScene = scene; + this.saveToMaterial = material; + + } + + this.saveToCurrent = this.saveTo; + + frame.renderer.render( this.saveToScene, this.camera, this.saveTo.renderTarget, this.saveTo.clear ); + +}; + +RTTNode.prototype.updateFrame = function ( frame ) { + + if ( frame.renderer ) { + + // from the second frame + + if ( this.saveTo && this.saveTo.render === false ) { + + this.updateFramesaveTo( frame ); + + } + + if ( this.render ) { + + if ( this.material.uniforms.renderTexture ) { + + this.material.uniforms.renderTexture.value = frame.renderTexture; + + } + + frame.renderer.render( this.scene, this.camera, this.renderTarget, this.clear ); + + } + + // first frame + + if ( this.saveTo && this.saveTo.render === true ) { + + this.updateFramesaveTo( frame ); + + } + + } else { + + console.warn( "RTTNode need a renderer in NodeFrame" ); + + } + +}; + +RTTNode.prototype.copy = function ( source ) { + + TextureNode.prototype.copy.call( this, source ); + + this.saveTo = source.saveTo; + +}; + +RTTNode.prototype.toJSON = function ( meta ) { + + var data = this.getJSONNode( meta ); + + if ( ! data ) { + + data = THREE.TextureNode.prototype.toJSON.call( this, meta ); + + if ( this.saveTo ) data.saveTo = this.saveTo.toJSON( meta ).uuid; + + } + + return data; + +}; + +export { RTTNode }; diff --git a/examples/js/nodes/inputs/ReflectorNode.js b/examples/js/nodes/inputs/ReflectorNode.js index d63e4a07e4ccaeb77cb1747a1f385e1d88b7f498..79e8f23ca65650609382851e491d0af91728d78a 100644 --- a/examples/js/nodes/inputs/ReflectorNode.js +++ b/examples/js/nodes/inputs/ReflectorNode.js @@ -14,7 +14,7 @@ function ReflectorNode( mirror ) { if ( mirror ) this.setMirror( mirror ); -}; +} ReflectorNode.prototype = Object.create( TempNode.prototype ); ReflectorNode.prototype.constructor = ReflectorNode; @@ -36,7 +36,7 @@ ReflectorNode.prototype.setMirror = function ( mirror ) { }; ReflectorNode.prototype.generate = function ( builder, output ) { - + if ( builder.isShader( 'fragment' ) ) { this.uvResult.a = this.offset; @@ -61,9 +61,9 @@ ReflectorNode.prototype.generate = function ( builder, output ) { }; ReflectorNode.prototype.copy = function ( source ) { - + InputNode.prototype.copy.call( this, source ); - + this.scope.mirror = source.mirror; }; diff --git a/examples/js/nodes/inputs/ScreenNode.js b/examples/js/nodes/inputs/ScreenNode.js index 0481fb841b70b47716c3b7fca14de73e7a642ae1..27740ee7931a15414bdfdfbf73e1d75c78b116a3 100644 --- a/examples/js/nodes/inputs/ScreenNode.js +++ b/examples/js/nodes/inputs/ScreenNode.js @@ -9,7 +9,7 @@ function ScreenNode( uv ) { TextureNode.call( this, undefined, uv ); -}; +} ScreenNode.prototype = Object.create( TextureNode.prototype ); ScreenNode.prototype.constructor = ScreenNode; diff --git a/examples/js/nodes/inputs/TextureNode.js b/examples/js/nodes/inputs/TextureNode.js index 7d7d972bfd1ae1601cf1d57380f74a30e9b4632a..ddb6d7096929708816395033b0ed569271af81fb 100644 --- a/examples/js/nodes/inputs/TextureNode.js +++ b/examples/js/nodes/inputs/TextureNode.js @@ -3,8 +3,8 @@ */ import { InputNode } from '../core/InputNode.js'; -import { NodeBuilder } from '../core/NodeBuilder.js'; import { UVNode } from '../accessors/UVNode.js'; +import { ColorSpaceNode } from '../utils/ColorSpaceNode.js'; function TextureNode( value, uv, bias, project ) { @@ -15,7 +15,7 @@ function TextureNode( value, uv, bias, project ) { this.bias = bias; this.project = project !== undefined ? project : false; -}; +} TextureNode.prototype = Object.create( InputNode.prototype ); TextureNode.prototype.constructor = TextureNode; @@ -53,23 +53,30 @@ TextureNode.prototype.generate = function ( builder, output ) { if ( bias ) code = method + '( ' + tex + ', ' + uv + ', ' + bias + ' )'; else code = method + '( ' + tex + ', ' + uv + ' )'; - code = builder.getTexelDecodingFunctionFromTexture( code, this.value ); + // add this context to replace ColorSpaceNode.input to code + + builder.addContext( { input: code, encoding: builder.getTextureEncodingFromMap( this.value ), include: builder.isShader( 'vertex' ) } ); + + this.colorSpace = this.colorSpace || new ColorSpaceNode( this ); + code = this.colorSpace.build( builder, this.type ); + + builder.removeContext(); return builder.format( code, this.type, output ); }; TextureNode.prototype.copy = function ( source ) { - + InputNode.prototype.copy.call( this, source ); - + if ( source.value ) this.value = source.value; this.uv = source.uv; if ( source.bias ) this.bias = source.bias; if ( source.project !== undefined ) this.project = source.project; - + }; TextureNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/inputs/Vector2Node.js b/examples/js/nodes/inputs/Vector2Node.js index 422f5d9ff59254a94f2d916ca30c6af307a68c9f..ebc4add3ae74b1af607c7a514f0c84828e5800c8 100644 --- a/examples/js/nodes/inputs/Vector2Node.js +++ b/examples/js/nodes/inputs/Vector2Node.js @@ -11,7 +11,7 @@ function Vector2Node( x, y ) { this.value = x instanceof THREE.Vector2 ? x : new THREE.Vector2( x, y ); -}; +} Vector2Node.prototype = Object.create( InputNode.prototype ); Vector2Node.prototype.constructor = Vector2Node; @@ -26,9 +26,9 @@ Vector2Node.prototype.generateReadonly = function ( builder, output, uuid, type, }; Vector2Node.prototype.copy = function ( source ) { - + InputNode.prototype.copy.call( this, source ); - + this.value.copy( source ); }; diff --git a/examples/js/nodes/inputs/Vector3Node.js b/examples/js/nodes/inputs/Vector3Node.js index 501cf665ccd73e3ad8e490f303a186208f31bb9a..71554d0f2782b816483d0a1eaa5d13b936d33020 100644 --- a/examples/js/nodes/inputs/Vector3Node.js +++ b/examples/js/nodes/inputs/Vector3Node.js @@ -11,7 +11,7 @@ function Vector3Node( x, y, z ) { this.value = x instanceof THREE.Vector3 ? x : new THREE.Vector3( x, y, z ); -}; +} Vector3Node.prototype = Object.create( InputNode.prototype ); Vector3Node.prototype.constructor = Vector3Node; @@ -26,11 +26,11 @@ Vector3Node.prototype.generateReadonly = function ( builder, output, uuid, type, }; Vector3Node.prototype.copy = function ( source ) { - + InputNode.prototype.copy.call( this, source ); - + this.value.copy( source ); - + }; Vector3Node.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/inputs/Vector4Node.js b/examples/js/nodes/inputs/Vector4Node.js index d98b72d2cfb0c70dd11f796ac5c689b21f6a0993..7bc4a977e8829a8da8a11e7d7a4237514e9c097d 100644 --- a/examples/js/nodes/inputs/Vector4Node.js +++ b/examples/js/nodes/inputs/Vector4Node.js @@ -11,7 +11,7 @@ function Vector4Node( x, y, z, w ) { this.value = x instanceof THREE.Vector4 ? x : new THREE.Vector4( x, y, z, w ); -}; +} Vector4Node.prototype = Object.create( InputNode.prototype ); Vector4Node.prototype.constructor = Vector4Node; @@ -26,9 +26,9 @@ Vector4Node.prototype.generateReadonly = function ( builder, output, uuid, type, }; Vector4Node.prototype.copy = function ( source ) { - + InputNode.prototype.copy.call( this, source ); - + this.value.copy( source ); }; diff --git a/examples/js/nodes/materials/MeshStandardNodeMaterial.js b/examples/js/nodes/materials/MeshStandardNodeMaterial.js index c7721749fa6033d2441ae2696351e3cd5603fd69..958f5bb6f781473591c0fb55a8a23490b7af4f65 100644 --- a/examples/js/nodes/materials/MeshStandardNodeMaterial.js +++ b/examples/js/nodes/materials/MeshStandardNodeMaterial.js @@ -14,7 +14,7 @@ function MeshStandardNodeMaterial() { this.type = "MeshStandardNodeMaterial"; -}; +} MeshStandardNodeMaterial.prototype = Object.create( NodeMaterial.prototype ); MeshStandardNodeMaterial.prototype.constructor = MeshStandardNodeMaterial; diff --git a/examples/js/nodes/materials/NodeMaterial.js b/examples/js/nodes/materials/NodeMaterial.js index 658fecd95f07238038f289b27279f7ded4bfd692..43d14deaa728e37ee990040df696e5856d132a6e 100644 --- a/examples/js/nodes/materials/NodeMaterial.js +++ b/examples/js/nodes/materials/NodeMaterial.js @@ -6,21 +6,17 @@ import { NodeBuilder } from '../core/NodeBuilder.js'; import { ColorNode } from '../inputs/ColorNode.js'; import { PositionNode } from '../accessors/PositionNode.js'; import { RawNode } from './nodes/RawNode.js'; - + function NodeMaterial( vertex, fragment ) { THREE.ShaderMaterial.call( this ); - // prevent code share conflict, remove in future - - this.defines.UUID = this.uuid; - this.vertex = vertex || new RawNode( new PositionNode( PositionNode.PROJECTION ) ); this.fragment = fragment || new RawNode( new ColorNode( 0xFF0000 ) ); this.updaters = []; -}; +} NodeMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype ); NodeMaterial.prototype.constructor = NodeMaterial; @@ -31,13 +27,13 @@ NodeMaterial.prototype.isNodeMaterial = true; Object.defineProperties( NodeMaterial.prototype, { properties: { - + get: function () { return this.fragment.properties; } - + } } ); @@ -71,47 +67,47 @@ NodeMaterial.prototype.build = function ( params ) { params = params || {}; var builder = params.builder || new NodeBuilder(); - + builder.setMaterial( this, params.renderer ); builder.build( this.vertex, this.fragment ); - - this.vertexShader = builder.getCode('vertex'); - this.fragmentShader = builder.getCode('fragment'); - + + this.vertexShader = builder.getCode( 'vertex' ); + this.fragmentShader = builder.getCode( 'fragment' ); + this.defines = builder.defines; this.uniforms = builder.uniforms; this.extensions = builder.extensions; this.updaters = builder.updaters; - + this.fog = builder.requires.fog; this.lights = builder.requires.lights; this.transparent = builder.requires.transparent || this.blending > THREE.NormalBlending; this.needsUpdate = false; - + return this; }; NodeMaterial.prototype.copy = function ( source ) { - + var uuid = this.uuid; - - for (var name in source) { - - this[name] = source[name]; - + + for ( var name in source ) { + + this[ name ] = source[ name ]; + } - + this.uuid = uuid; - - if ( source.userData !== undefined) { - + + if ( source.userData !== undefined ) { + this.userData = JSON.parse( JSON.stringify( source.userData ) ); - + } - + }; NodeMaterial.prototype.toJSON = function ( meta ) { @@ -157,7 +153,7 @@ NodeMaterial.prototype.toJSON = function ( meta ) { if ( this.scale !== undefined ) data.scale = this.scale; if ( this.dithering === true ) data.dithering = true; - + if ( this.wireframe === true ) data.wireframe = this.wireframe; if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth; if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap; @@ -165,7 +161,7 @@ NodeMaterial.prototype.toJSON = function ( meta ) { if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest; if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha; - + if ( this.morphTargets === true ) data.morphTargets = true; if ( this.skinning === true ) data.skinning = true; @@ -174,7 +170,7 @@ NodeMaterial.prototype.toJSON = function ( meta ) { data.fog = this.fog; data.lights = this.lights; - + data.vertex = this.vertex.toJSON( meta ).uuid; data.fragment = this.fragment.toJSON( meta ).uuid; diff --git a/examples/js/nodes/materials/PhongNodeMaterial.js b/examples/js/nodes/materials/PhongNodeMaterial.js index aaa9993a66e651e696ffb8b76ba7efb1c2d09947..22b6fec5d40b9146e905e3ffa0e311cc191612fb 100644 --- a/examples/js/nodes/materials/PhongNodeMaterial.js +++ b/examples/js/nodes/materials/PhongNodeMaterial.js @@ -14,25 +14,25 @@ function PhongNodeMaterial() { this.type = "PhongNodeMaterial"; -}; +} PhongNodeMaterial.prototype = Object.create( NodeMaterial.prototype ); PhongNodeMaterial.prototype.constructor = PhongNodeMaterial; -NodeUtils.addShortcuts( PhongNodeMaterial.prototype, 'fragment', [ - 'color', - 'alpha', - 'specular', - 'shininess', - 'normal', - 'emissive', - 'ambient', - 'light', - 'shadow', - 'ao', - 'environment', +NodeUtils.addShortcuts( PhongNodeMaterial.prototype, 'fragment', [ + 'color', + 'alpha', + 'specular', + 'shininess', + 'normal', + 'emissive', + 'ambient', + 'light', + 'shadow', + 'ao', + 'environment', 'environmentAlpha', - 'transform' + 'position' ] ); export { PhongNodeMaterial }; diff --git a/examples/js/nodes/materials/SpriteNodeMaterial.js b/examples/js/nodes/materials/SpriteNodeMaterial.js index 0178215dda7abfccd0a5982ed605267acc1d5f88..c0f080d165399f7c66a113f8f8c04b7865c8437b 100644 --- a/examples/js/nodes/materials/SpriteNodeMaterial.js +++ b/examples/js/nodes/materials/SpriteNodeMaterial.js @@ -14,16 +14,16 @@ function SpriteNodeMaterial() { this.type = "SpriteNodeMaterial"; -}; +} SpriteNodeMaterial.prototype = Object.create( NodeMaterial.prototype ); SpriteNodeMaterial.prototype.constructor = SpriteNodeMaterial; -NodeUtils.addShortcuts( SpriteNodeMaterial.prototype, 'fragment', [ - 'color', - 'alpha', - 'transform', - 'spherical' +NodeUtils.addShortcuts( SpriteNodeMaterial.prototype, 'fragment', [ + 'color', + 'alpha', + 'position', + 'spherical' ] ); export { SpriteNodeMaterial }; diff --git a/examples/js/nodes/materials/StandardNodeMaterial.js b/examples/js/nodes/materials/StandardNodeMaterial.js index 994bf8ed3af5cbb2ef02508f28d50e826b85dd1c..3cdcef92ac3876bfe2ff0cd3a9c0e814690a4998 100644 --- a/examples/js/nodes/materials/StandardNodeMaterial.js +++ b/examples/js/nodes/materials/StandardNodeMaterial.js @@ -14,27 +14,27 @@ function StandardNodeMaterial() { this.type = "StandardNodeMaterial"; -}; +} StandardNodeMaterial.prototype = Object.create( NodeMaterial.prototype ); StandardNodeMaterial.prototype.constructor = StandardNodeMaterial; -NodeUtils.addShortcuts( StandardNodeMaterial.prototype, 'fragment', [ - 'color', - 'alpha', - 'roughness', - 'metalness', - 'reflectivity', - 'clearCoat', - 'clearCoatRoughness', - 'normal', - 'emissive', - 'ambient', - 'light', - 'shadow', - 'ao', - 'environment', - 'transform' +NodeUtils.addShortcuts( StandardNodeMaterial.prototype, 'fragment', [ + 'color', + 'alpha', + 'roughness', + 'metalness', + 'reflectivity', + 'clearCoat', + 'clearCoatRoughness', + 'normal', + 'emissive', + 'ambient', + 'light', + 'shadow', + 'ao', + 'environment', + 'position' ] ); export { StandardNodeMaterial }; diff --git a/examples/js/nodes/materials/nodes/MeshStandardNode.js b/examples/js/nodes/materials/nodes/MeshStandardNode.js index 2dd1101e15a6751a23bb753e3ec47a832511cedd..79b60e63dc793f445c26ed40ac14c3c63efecf4d 100644 --- a/examples/js/nodes/materials/nodes/MeshStandardNode.js +++ b/examples/js/nodes/materials/nodes/MeshStandardNode.js @@ -18,7 +18,7 @@ function MeshStandardNode() { metalness: 0.5, normalScale: new THREE.Vector2( 1, 1 ) }; - + this.inputs = { color: new PropertyNode( this.properties, 'color', 'c' ), roughness: new PropertyNode( this.properties, 'roughness', 'f' ), @@ -26,7 +26,7 @@ function MeshStandardNode() { normalScale: new PropertyNode( this.properties, 'normalScale', 'v2' ) }; -}; +} MeshStandardNode.prototype = Object.create( StandardNode.prototype ); MeshStandardNode.prototype.constructor = MeshStandardNode; @@ -37,53 +37,57 @@ MeshStandardNode.prototype.build = function ( builder ) { var props = this.properties, inputs = this.inputs; - if ( builder.isShader('fragment') ) { - + if ( builder.isShader( 'fragment' ) ) { + // slots // * color // * map - + var color = builder.findNode( props.color, inputs.color ), map = builder.resolve( props.map ); - + this.color = map ? new OperatorNode( color, map, OperatorNode.MUL ) : color; - + // slots // * roughness // * roughnessMap - + var roughness = builder.findNode( props.roughness, inputs.roughness ), roughnessMap = builder.resolve( props.roughnessMap ); - + this.roughness = roughnessMap ? new OperatorNode( roughness, new SwitchNode( roughnessMap, "g" ), OperatorNode.MUL ) : roughness; - + // slots // * metalness // * metalnessMap - + var metalness = builder.findNode( props.metalness, inputs.metalness ), metalnessMap = builder.resolve( props.metalnessMap ); - + this.metalness = metalnessMap ? new OperatorNode( metalness, new SwitchNode( metalnessMap, "b" ), OperatorNode.MUL ) : metalness; // slots // * normalMap // * normalScale - + if ( props.normalMap ) { - + this.normal = new NormalMapNode( builder.resolve( props.normalMap ) ); - this.normal.scale = builder.findNode( props.normalScale, inputs.normalScale ) + this.normal.scale = builder.findNode( props.normalScale, inputs.normalScale ); + + } else { + + this.normal = undefined; } // slots // * envMap - + this.environment = builder.resolve( props.envMap ); - + } - + // build code return StandardNode.prototype.build.call( this, builder ); @@ -97,9 +101,9 @@ MeshStandardNode.prototype.toJSON = function ( meta ) { if ( ! data ) { data = this.createJSONNode( meta ); - - console.warn(".toJSON not implemented in", this); - + + console.warn( ".toJSON not implemented in", this ); + } return data; diff --git a/examples/js/nodes/materials/nodes/PhongNode.js b/examples/js/nodes/materials/nodes/PhongNode.js index 907a271c82c5d17ff389d205f2ba97380c7e38a1..9a79b6793878fd96015179612847189031639731 100644 --- a/examples/js/nodes/materials/nodes/PhongNode.js +++ b/examples/js/nodes/materials/nodes/PhongNode.js @@ -2,21 +2,21 @@ * @author sunag / http://www.sunag.com.br/ */ -import { GLNode } from '../../core/GLNode.js'; +import { Node } from '../../core/Node.js'; import { ColorNode } from '../../inputs/ColorNode.js'; import { FloatNode } from '../../inputs/FloatNode.js'; - + function PhongNode() { - GLNode.call( this ); + Node.call( this ); this.color = new ColorNode( 0xEEEEEE ); this.specular = new ColorNode( 0x111111 ); this.shininess = new FloatNode( 30 ); -}; +} -PhongNode.prototype = Object.create( GLNode.prototype ); +PhongNode.prototype = Object.create( Node.prototype ); PhongNode.prototype.constructor = PhongNode; PhongNode.prototype.nodeType = "Phong"; @@ -25,18 +25,17 @@ PhongNode.prototype.build = function ( builder ) { var code; builder.define( 'PHONG' ); - builder.define( 'ALPHATEST', '0.0' ); builder.requires.lights = true; if ( builder.isShader( 'vertex' ) ) { - var transform = this.transform ? this.transform.parseAndBuildCode( builder, 'v3', { cache: 'transform' } ) : undefined; + var position = this.position ? this.position.parseAndBuildCode( builder, 'v3', { cache: 'position' } ) : undefined; builder.mergeUniform( THREE.UniformsUtils.merge( [ - THREE.UniformsLib[ "fog" ], - THREE.UniformsLib[ "lights" ] + THREE.UniformsLib.fog, + THREE.UniformsLib.lights ] ) ); @@ -49,13 +48,13 @@ PhongNode.prototype.build = function ( builder ) { "#endif", - "#include ", - "#include ", // encoding functions + //"#include ", // encoding functions "#include ", "#include ", "#include ", "#include ", - "#include " + "#include ", + "#include " ].join( "\n" ) ); var output = [ @@ -65,7 +64,7 @@ PhongNode.prototype.build = function ( builder ) { "#include ", "#include ", - "#ifndef FLAT_SHADED", // Normal computed with derivatives when FLAT_SHADED + "#ifndef FLAT_SHADED", // normal computed with derivatives when FLAT_SHADED " vNormal = normalize( transformedNormal );", @@ -74,11 +73,11 @@ PhongNode.prototype.build = function ( builder ) { "#include " ]; - if ( transform ) { + if ( position ) { output.push( - transform.code, - transform.result ? "transformed = " + transform.result + ";" : '' + position.code, + position.result ? "transformed = " + position.result + ";" : '' ); } @@ -89,11 +88,13 @@ PhongNode.prototype.build = function ( builder ) { " #include ", " #include ", " #include ", + " #include ", " vViewPosition = - mvPosition.xyz;", " #include ", - " #include " + " #include ", + " #include " ); code = output.join( "\n" ); @@ -109,7 +110,6 @@ PhongNode.prototype.build = function ( builder ) { if ( this.alpha ) this.alpha.parse( builder ); if ( this.normal ) this.normal.parse( builder ); - if ( this.normalScale && this.normal ) this.normalScale.parse( builder ); if ( this.light ) this.light.parse( builder, { cache: 'light' } ); @@ -130,7 +130,6 @@ PhongNode.prototype.build = function ( builder ) { var alpha = this.alpha ? this.alpha.buildCode( builder, 'f' ) : undefined; var normal = this.normal ? this.normal.buildCode( builder, 'v3' ) : undefined; - var normalScale = this.normalScale && this.normal ? this.normalScale.buildCode( builder, 'v2' ) : undefined; var light = this.light ? this.light.buildCode( builder, 'v3', { cache: 'light' } ) : undefined; @@ -145,7 +144,6 @@ PhongNode.prototype.build = function ( builder ) { builder.requires.transparent = alpha != undefined; builder.addParsCode( [ - "#include ", "#include ", "#include ", "#include ", @@ -180,7 +178,11 @@ PhongNode.prototype.build = function ( builder ) { output.push( alpha.code, - 'if ( ' + alpha.result + ' <= ALPHATEST ) discard;' + '#ifdef ALPHATEST', + + 'if ( ' + alpha.result + ' <= ALPHATEST ) discard;', + + '#endif' ); } @@ -191,7 +193,7 @@ PhongNode.prototype.build = function ( builder ) { normal.code, 'normal = ' + normal.result + ';' ); - + } // optimization for now @@ -281,19 +283,19 @@ PhongNode.prototype.build = function ( builder ) { } } -/* + /* switch( builder.material.combine ) { case THREE.ENVMAP_BLENDING_MULTIPLY: - + //output.push( "vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular;" ); //outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity ); - + break; - - + + } - */ + */ if ( alpha ) { output.push( "gl_FragColor = vec4( outgoingLight, " + alpha.result + " );" ); @@ -320,12 +322,12 @@ PhongNode.prototype.build = function ( builder ) { }; PhongNode.prototype.copy = function ( source ) { - - GLNode.prototype.copy.call( this, source ); - + + Node.prototype.copy.call( this, source ); + // vertex - if ( source.transform ) this.transform = source.transform; + if ( source.position ) this.position = source.position; // fragment @@ -341,7 +343,7 @@ PhongNode.prototype.copy = function ( source ) { if ( source.shadow ) this.shadow = source.shadow; if ( source.ao ) this.ao = source.ao; - + if ( source.emissive ) this.emissive = source.emissive; if ( source.ambient ) this.ambient = source.ambient; @@ -360,7 +362,7 @@ PhongNode.prototype.toJSON = function ( meta ) { // vertex - if ( this.transform ) data.transform = this.transform.toJSON( meta ).uuid; + if ( this.position ) data.position = this.position.toJSON( meta ).uuid; // fragment diff --git a/examples/js/nodes/materials/nodes/RawNode.js b/examples/js/nodes/materials/nodes/RawNode.js index 1430bb1adc192963e436f69ca2afc9e842bfbfa4..125a97e6c379a6f5341eaebf4fde4877c0794208 100644 --- a/examples/js/nodes/materials/nodes/RawNode.js +++ b/examples/js/nodes/materials/nodes/RawNode.js @@ -2,17 +2,17 @@ * @author sunag / http://www.sunag.com.br/ */ -import { GLNode } from '../../core/GLNode.js'; +import { Node } from '../../core/Node.js'; function RawNode( value ) { - GLNode.call( this, 'v4' ); + Node.call( this, 'v4' ); this.value = value; -}; +} -RawNode.prototype = Object.create( GLNode.prototype ); +RawNode.prototype = Object.create( Node.prototype ); RawNode.prototype.constructor = RawNode; RawNode.prototype.nodeType = "Raw"; @@ -36,11 +36,11 @@ RawNode.prototype.generate = function ( builder ) { }; RawNode.prototype.copy = function ( source ) { - - GLNode.prototype.copy.call( this, source ); - + + Node.prototype.copy.call( this, source ); + this.value = source.value; - + }; RawNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/materials/nodes/SpriteNode.js b/examples/js/nodes/materials/nodes/SpriteNode.js index f00b56a02ef5eabf8265b34b2f513019f024fde3..f3d23822b22c7e0ed54ce3015a012e5ba88d861c 100644 --- a/examples/js/nodes/materials/nodes/SpriteNode.js +++ b/examples/js/nodes/materials/nodes/SpriteNode.js @@ -2,19 +2,19 @@ * @author sunag / http://www.sunag.com.br/ */ -import { GLNode } from '../../core/GLNode.js'; +import { Node } from '../../core/Node.js'; import { ColorNode } from '../../inputs/ColorNode.js'; function SpriteNode() { - GLNode.call( this ); + Node.call( this ); this.color = new ColorNode( 0xEEEEEE ); this.spherical = true; -}; +} -SpriteNode.prototype = Object.create( GLNode.prototype ); +SpriteNode.prototype = Object.create( Node.prototype ); SpriteNode.prototype.constructor = SpriteNode; SpriteNode.prototype.nodeType = "Sprite"; @@ -25,29 +25,32 @@ SpriteNode.prototype.build = function ( builder ) { builder.define( 'SPRITE' ); builder.requires.lights = false; - builder.requires.transparent = this.alpha != undefined; + builder.requires.transparent = this.alpha !== undefined; if ( builder.isShader( 'vertex' ) ) { - var transform = this.transform ? this.transform.parseAndBuildCode( builder, 'v3', { cache: 'transform' } ) : undefined; + var position = this.position ? this.position.parseAndBuildCode( builder, 'v3', { cache: 'position' } ) : undefined; builder.mergeUniform( THREE.UniformsUtils.merge( [ - THREE.UniformsLib[ "fog" ] + THREE.UniformsLib.fog ] ) ); builder.addParsCode( [ - "#include " + "#include ", + "#include ", + "#include " ].join( "\n" ) ); output = [ + "#include ", "#include " ]; - if ( transform ) { + if ( position ) { output.push( - transform.code, - transform.result ? "transformed = " + transform.result + ";" : '' + position.code, + position.result ? "transformed = " + position.result + ";" : '' ); } @@ -98,43 +101,64 @@ SpriteNode.prototype.build = function ( builder ) { 'modelViewMtx[2][1] = 0.0;', 'modelViewMtx[2][2] = 1.0;', - // apply - 'gl_Position = projectionMatrix * modelViewMtx * modelMtx * vec4( transformed, 1.0 );' + "gl_Position = projectionMatrix * modelViewMtx * modelMtx * vec4( transformed, 1.0 );", + + "#include ", + "#include ", + "#include " ); } else { builder.addParsCode( [ "#include ", + "#include ", + "#include " ].join( "\n" ) ); - // parse all nodes to reuse generate codes + builder.addCode( [ + "#include ", + "#include " + ].join( "\n" ) ); - this.color.parse( builder, { slot: 'color' } ); + // parse all nodes to reuse generate codes if ( this.alpha ) this.alpha.parse( builder ); - // build code + this.color.parse( builder, { slot: 'color' } ); - var color = this.color.buildCode( builder, 'c', { slot: 'color' } ); - var alpha = this.alpha ? this.alpha.buildCode( builder, 'f' ) : undefined; + // build code - output = [ color.code ]; + var alpha = this.alpha ? this.alpha.buildCode( builder, 'f' ) : undefined, + color = this.color.buildCode( builder, 'c', { slot: 'color' } ); if ( alpha ) { - output.push( + output = [ alpha.code, + '#ifdef ALPHATEST', + + 'if ( ' + alpha.result + ' <= ALPHATEST ) discard;', + + '#endif', + color.code, "gl_FragColor = vec4( " + color.result + ", " + alpha.result + " );" - ); + ]; } else { - output.push( "gl_FragColor = vec4( " + color.result + ", 1.0 );" ); + output = [ + color.code, + "gl_FragColor = vec4( " + color.result + ", 1.0 );" + ]; } - output.push( "#include " ); + output.push( + "#include ", + "#include ", + "#include " + ); } @@ -143,19 +167,19 @@ SpriteNode.prototype.build = function ( builder ) { }; SpriteNode.prototype.copy = function ( source ) { - - GLNode.prototype.copy.call( this, source ); - + + Node.prototype.copy.call( this, source ); + // vertex - - if ( source.transform ) this.transform = source.transform; - + + if ( source.position ) this.position = source.position; + // fragment - + this.color = source.color; - - if ( source.spherical !== undefined ) this.spherical = source.transform; - + + if ( source.spherical !== undefined ) this.spherical = source.spherical; + if ( source.alpha ) this.alpha = source.alpha; }; @@ -170,12 +194,12 @@ SpriteNode.prototype.toJSON = function ( meta ) { // vertex - if ( this.transform ) data.transform = this.transform.toJSON( meta ).uuid; + if ( this.position ) data.position = this.position.toJSON( meta ).uuid; // fragment data.color = this.color.toJSON( meta ).uuid; - + if ( this.spherical === false ) data.spherical = false; if ( this.alpha ) data.alpha = this.alpha.toJSON( meta ).uuid; diff --git a/examples/js/nodes/materials/nodes/StandardNode.js b/examples/js/nodes/materials/nodes/StandardNode.js index b3ad1fa600906b9d6c0a2a86084b364e62720f56..97bfaed60063b45e4acb693e0392f6098df42a56 100644 --- a/examples/js/nodes/materials/nodes/StandardNode.js +++ b/examples/js/nodes/materials/nodes/StandardNode.js @@ -2,22 +2,22 @@ * @author sunag / http://www.sunag.com.br/ */ -import { GLNode } from '../../core/GLNode.js'; +import { Node } from '../../core/Node.js'; import { ColorNode } from '../../inputs/ColorNode.js'; import { FloatNode } from '../../inputs/FloatNode.js'; import { RoughnessToBlinnExponentNode } from '../../bsdfs/RoughnessToBlinnExponentNode.js'; - + function StandardNode() { - GLNode.call( this ); + Node.call( this ); this.color = new ColorNode( 0xEEEEEE ); this.roughness = new FloatNode( 0.5 ); this.metalness = new FloatNode( 0.5 ); -}; +} -StandardNode.prototype = Object.create( GLNode.prototype ); +StandardNode.prototype = Object.create( Node.prototype ); StandardNode.prototype.constructor = StandardNode; StandardNode.prototype.nodeType = "Standard"; @@ -26,7 +26,6 @@ StandardNode.prototype.build = function ( builder ) { var code; builder.define( this.clearCoat || this.clearCoatRoughness ? 'PHYSICAL' : 'STANDARD' ); - builder.define( 'ALPHATEST', '0.0' ); builder.requires.lights = true; @@ -34,12 +33,12 @@ StandardNode.prototype.build = function ( builder ) { if ( builder.isShader( 'vertex' ) ) { - var transform = this.transform ? this.transform.parseAndBuildCode( builder, 'v3', { cache: 'transform' } ) : undefined; + var position = this.position ? this.position.parseAndBuildCode( builder, 'v3', { cache: 'position' } ) : undefined; builder.mergeUniform( THREE.UniformsUtils.merge( [ - THREE.UniformsLib[ "fog" ], - THREE.UniformsLib[ "lights" ] + THREE.UniformsLib.fog, + THREE.UniformsLib.lights ] ) ); @@ -52,13 +51,13 @@ StandardNode.prototype.build = function ( builder ) { "#endif", - "#include ", - "#include ", // encoding functions + //"#include ", // encoding functions "#include ", "#include ", "#include ", "#include ", - "#include " + "#include ", + "#include " ].join( "\n" ) ); @@ -68,9 +67,6 @@ StandardNode.prototype.build = function ( builder ) { "#include ", "#include ", "#include ", - "#include ", - "#include ", - "#include ", "#ifndef FLAT_SHADED", // Normal computed with derivatives when FLAT_SHADED @@ -81,11 +77,11 @@ StandardNode.prototype.build = function ( builder ) { "#include " ]; - if ( transform ) { + if ( position ) { output.push( - transform.code, - transform.result ? "transformed = " + transform.result + ";" : '' + position.code, + position.result ? "transformed = " + position.result + ";" : '' ); } @@ -96,6 +92,7 @@ StandardNode.prototype.build = function ( builder ) { "#include ", "#include ", "#include ", + "#include ", " vViewPosition = - mvPosition.xyz;", @@ -127,7 +124,6 @@ StandardNode.prototype.build = function ( builder ) { if ( this.alpha ) this.alpha.parse( builder ); if ( this.normal ) this.normal.parse( builder ); - if ( this.normalScale && this.normal ) this.normalScale.parse( builder ); if ( this.clearCoat ) this.clearCoat.parse( builder ); if ( this.clearCoatRoughness ) this.clearCoatRoughness.parse( builder ); @@ -152,7 +148,6 @@ StandardNode.prototype.build = function ( builder ) { var alpha = this.alpha ? this.alpha.buildCode( builder, 'f' ) : undefined; var normal = this.normal ? this.normal.buildCode( builder, 'v3' ) : undefined; - var normalScale = this.normalScale && this.normal ? this.normalScale.buildCode( builder, 'v2' ) : undefined; var clearCoat = this.clearCoat ? this.clearCoat.buildCode( builder, 'f' ) : undefined; var clearCoatRoughness = this.clearCoatRoughness ? this.clearCoatRoughness.buildCode( builder, 'f' ) : undefined; @@ -182,7 +177,7 @@ StandardNode.prototype.build = function ( builder ) { "#endif", - "#include ", + "#include ", "#include ", "#include ", "#include ", @@ -193,10 +188,12 @@ StandardNode.prototype.build = function ( builder ) { ].join( "\n" ) ); var output = [ - // prevent undeclared normal + "#include ", + + // add before: prevent undeclared normal " #include ", - // prevent undeclared material + // add before: prevent undeclared material " PhysicalMaterial material;", " material.diffuseColor = vec3( 1.0 );", @@ -217,7 +214,11 @@ StandardNode.prototype.build = function ( builder ) { output.push( alpha.code, - 'if ( ' + alpha.result + ' <= ALPHATEST ) discard;' + '#ifdef ALPHATEST', + + 'if ( ' + alpha.result + ' <= ALPHATEST ) discard;', + + '#endif' ); } @@ -228,7 +229,7 @@ StandardNode.prototype.build = function ( builder ) { normal.code, 'normal = ' + normal.result + ';' ); - + } // optimization for now @@ -356,7 +357,7 @@ StandardNode.prototype.build = function ( builder ) { output.push( "radiance += " + environment.result + ";" ); } - + output.push( "#include " ); @@ -374,7 +375,6 @@ StandardNode.prototype.build = function ( builder ) { } output.push( - "#include ", "#include ", "#include ", "#include ", @@ -391,12 +391,12 @@ StandardNode.prototype.build = function ( builder ) { }; StandardNode.prototype.copy = function ( source ) { - - GLNode.prototype.copy.call( this, source ); - + + Node.prototype.copy.call( this, source ); + // vertex - if ( source.transform ) this.transform = source.transform; + if ( source.position ) this.position = source.position; // fragment @@ -417,7 +417,7 @@ StandardNode.prototype.copy = function ( source ) { if ( source.shadow ) this.shadow = source.shadow; if ( source.ao ) this.ao = source.ao; - + if ( source.emissive ) this.emissive = source.emissive; if ( source.ambient ) this.ambient = source.ambient; @@ -435,7 +435,7 @@ StandardNode.prototype.toJSON = function ( meta ) { // vertex - if ( this.transform ) data.transform = this.transform.toJSON( meta ).uuid; + if ( this.position ) data.position = this.position.toJSON( meta ).uuid; // fragment @@ -456,7 +456,7 @@ StandardNode.prototype.toJSON = function ( meta ) { if ( this.shadow ) data.shadow = this.shadow.toJSON( meta ).uuid; if ( this.ao ) data.ao = this.ao.toJSON( meta ).uuid; - + if ( this.emissive ) data.emissive = this.emissive.toJSON( meta ).uuid; if ( this.ambient ) data.ambient = this.ambient.toJSON( meta ).uuid; diff --git a/examples/js/nodes/math/CondNode.js b/examples/js/nodes/math/CondNode.js new file mode 100644 index 0000000000000000000000000000000000000000..484a1cacd2117d54df87b1a99eda2fc202bd5ad6 --- /dev/null +++ b/examples/js/nodes/math/CondNode.js @@ -0,0 +1,107 @@ +/** + * @author sunag / http://www.sunag.com.br/ + */ + +import { TempNode } from '../core/TempNode.js'; + +function CondNode( a, b, ifNode, elseNode, op ) { + + TempNode.call( this ); + + this.a = a; + this.b = b; + + this.ifNode = ifNode; + this.elseNode = elseNode; + + this.op = op; + +} + +CondNode.EQUAL = '=='; +CondNode.NOT_EQUAL = '!='; +CondNode.GREATER = '>'; +CondNode.GREATER_EQUAL = '>='; +CondNode.LESS = '<'; +CondNode.LESS_EQUAL = '<='; + +CondNode.prototype = Object.create( TempNode.prototype ); +CondNode.prototype.constructor = CondNode; +CondNode.prototype.nodeType = "Cond"; + +CondNode.prototype.getType = function ( builder ) { + + if ( builder.getTypeLength( this.elseNode.getType( builder ) ) > builder.getTypeLength( this.ifNode.getType( builder ) ) ) { + + return this.elseNode.getType( builder ); + + } + + return this.ifNode.getType( builder ); + +}; + +CondNode.prototype.getCondType = function ( builder ) { + + if ( builder.getTypeLength( this.b.getType( builder ) ) > builder.getTypeLength( this.a.getType( builder ) ) ) { + + return this.b.getType( builder ); + + } + + return this.a.getType( builder ); + +}; + +CondNode.prototype.generate = function ( builder, output ) { + + var type = this.getType( builder ), + condType = this.getCondType( builder ), + a = this.a.build( builder, condType ), + b = this.b.build( builder, condType ), + ifNode = this.ifNode.build( builder, type ), + elseNode = this.elseNode.build( builder, type ); + + var code = '( ' + [ a, this.op, b, '?', ifNode, ':', elseNode ].join( ' ' ) + ' )'; + + return builder.format( code, this.getType( builder ), output ); + +}; + +CondNode.prototype.copy = function ( source ) { + + TempNode.prototype.copy.call( this, source ); + + this.a = source.a; + this.b = source.b; + + this.ifNode = source.ifNode; + this.elseNode = source.elseNode; + + this.op = source.op; + +}; + +CondNode.prototype.toJSON = function ( meta ) { + + var data = this.getJSONNode( meta ); + + if ( ! data ) { + + data = this.createJSONNode( meta ); + + data.a = this.a.toJSON( meta ).uuid; + data.b = this.b.toJSON( meta ).uuid; + + data.ifNode = this.ifNode.toJSON( meta ).uuid; + data.elseNode = this.elseNode.toJSON( meta ).uuid; + + data.op = this.op; + + } + + return data; + +}; + +export { CondNode }; diff --git a/examples/js/nodes/math/Math1Node.js b/examples/js/nodes/math/Math1Node.js index 7b311007fa834a66b74d77dad1347ce155ada9d2..5d76fefea80b8ca997327ac7c0bd5f262393e542 100644 --- a/examples/js/nodes/math/Math1Node.js +++ b/examples/js/nodes/math/Math1Node.js @@ -10,9 +10,9 @@ function Math1Node( a, method ) { this.a = a; - this.method = method || Math1Node.SIN; + this.method = method; -}; +} Math1Node.RAD = 'radians'; Math1Node.DEG = 'degrees'; @@ -48,7 +48,7 @@ Math1Node.prototype.getType = function ( builder ) { switch ( this.method ) { case Math1Node.LENGTH: - + return 'f'; } @@ -65,21 +65,21 @@ Math1Node.prototype.generate = function ( builder, output ) { switch ( this.method ) { case Math1Node.NEGATE: - + result = '( -' + result + ' )'; - + break; case Math1Node.INVERT: - + result = '( 1.0 - ' + result + ' )'; - + break; default: - + result = this.method + '( ' + result + ' )'; - + break; } @@ -89,12 +89,12 @@ Math1Node.prototype.generate = function ( builder, output ) { }; Math1Node.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.a = source.a; this.method = source.method; - + }; Math1Node.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/math/Math2Node.js b/examples/js/nodes/math/Math2Node.js index 70f82b6dabd6c90577f398b5de098db56dfda0fd..85d773b534da8e8e956ad382f0c524a51db1018f 100644 --- a/examples/js/nodes/math/Math2Node.js +++ b/examples/js/nodes/math/Math2Node.js @@ -1,7 +1,7 @@ /** * @author sunag / http://www.sunag.com.br/ */ - + import { TempNode } from '../core/TempNode.js'; function Math2Node( a, b, method ) { @@ -11,9 +11,9 @@ function Math2Node( a, b, method ) { this.a = a; this.b = b; - this.method = method || Math2Node.DISTANCE; + this.method = method; -}; +} Math2Node.MIN = 'min'; Math2Node.MAX = 'max'; @@ -32,7 +32,7 @@ Math2Node.prototype.nodeType = "Math2"; Math2Node.prototype.getInputType = function ( builder ) { // use the greater length vector - + if ( builder.getTypeLength( this.b.getType( builder ) ) > builder.getTypeLength( this.a.getType( builder ) ) ) { return this.b.getType( builder ); @@ -49,11 +49,11 @@ Math2Node.prototype.getType = function ( builder ) { case Math2Node.DISTANCE: case Math2Node.DOT: - + return 'f'; case Math2Node.CROSS: - + return 'v3'; } @@ -64,43 +64,43 @@ Math2Node.prototype.getType = function ( builder ) { Math2Node.prototype.generate = function ( builder, output ) { - var a, b, + var a, b, type = this.getInputType( builder ), al = builder.getTypeLength( this.a.getType( builder ) ), bl = builder.getTypeLength( this.b.getType( builder ) ); - + // optimzer switch ( this.method ) { case Math2Node.CROSS: - + a = this.a.build( builder, 'v3' ); b = this.b.build( builder, 'v3' ); - + break; case Math2Node.STEP: - + a = this.a.build( builder, al === 1 ? 'f' : type ); b = this.b.build( builder, type ); - + break; case Math2Node.MIN: case Math2Node.MAX: case Math2Node.MOD: - + a = this.a.build( builder, type ); b = this.b.build( builder, bl === 1 ? 'f' : type ); - + break; default: - + a = this.a.build( builder, type ); b = this.b.build( builder, type ); - + break; } @@ -110,13 +110,13 @@ Math2Node.prototype.generate = function ( builder, output ) { }; Math2Node.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.a = source.a; this.b = source.b; this.method = source.method; - + }; Math2Node.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/math/Math3Node.js b/examples/js/nodes/math/Math3Node.js index c228f40194a9b9c5c942d14183a7585114e656dc..6a9f295d8875239ca907c8ad1506e4f570d294e0 100644 --- a/examples/js/nodes/math/Math3Node.js +++ b/examples/js/nodes/math/Math3Node.js @@ -1,7 +1,7 @@ /** * @author sunag / http://www.sunag.com.br/ */ - + import { TempNode } from '../core/TempNode.js'; function Math3Node( a, b, c, method ) { @@ -12,9 +12,9 @@ function Math3Node( a, b, c, method ) { this.b = b; this.c = c; - this.method = method || Math3Node.MIX; + this.method = method; -}; +} Math3Node.MIX = 'mix'; Math3Node.REFRACT = 'refract'; @@ -32,13 +32,13 @@ Math3Node.prototype.getType = function ( builder ) { var c = builder.getTypeLength( this.c.getType( builder ) ); if ( a > b && a > c ) { - + return this.a.getType( builder ); - + } else if ( b > c ) { - + return this.b.getType( builder ); - + } return this.c.getType( builder ); @@ -58,27 +58,27 @@ Math3Node.prototype.generate = function ( builder, output ) { switch ( this.method ) { case Math3Node.REFRACT: - + a = this.a.build( builder, type ); b = this.b.build( builder, type ); c = this.c.build( builder, 'f' ); - + break; case Math3Node.MIX: - + a = this.a.build( builder, type ); b = this.b.build( builder, type ); c = this.c.build( builder, cl === 1 ? 'f' : type ); - + break; default: - + a = this.a.build( builder, type ); b = this.b.build( builder, type ); c = this.c.build( builder, type ); - + break; } @@ -88,14 +88,14 @@ Math3Node.prototype.generate = function ( builder, output ) { }; Math3Node.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.a = source.a; this.b = source.b; this.c = source.c; this.method = source.method; - + }; Math3Node.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/math/OperatorNode.js b/examples/js/nodes/math/OperatorNode.js index 35a42c003d8618b39f89e209effd629676c21269..b6044321f9c4961fb2e543e2201f4495b8ef6527 100644 --- a/examples/js/nodes/math/OperatorNode.js +++ b/examples/js/nodes/math/OperatorNode.js @@ -3,16 +3,16 @@ */ import { TempNode } from '../core/TempNode.js'; - + function OperatorNode( a, b, op ) { TempNode.call( this ); this.a = a; this.b = b; - this.op = op || OperatorNode.ADD; + this.op = op; -}; +} OperatorNode.ADD = '+'; OperatorNode.SUB = '-'; @@ -52,18 +52,18 @@ OperatorNode.prototype.generate = function ( builder, output ) { var a = this.a.build( builder, type ), b = this.b.build( builder, type ); - return builder.format( '( ' + a + ' ' + this.op + ' '+ b + ' )', type, output ); + return builder.format( '( ' + a + ' ' + this.op + ' ' + b + ' )', type, output ); }; OperatorNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.a = source.a; this.b = source.b; this.op = source.op; - + }; OperatorNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/misc/BumpMapNode.js b/examples/js/nodes/misc/BumpMapNode.js index c596db95c60c61d3ed220f83a88fbfd7de0f8d08..f5f45b1df98c77062fa600adb625aa66f8073c96 100644 --- a/examples/js/nodes/misc/BumpMapNode.js +++ b/examples/js/nodes/misc/BumpMapNode.js @@ -16,31 +16,31 @@ function BumpMapNode( value, scale ) { this.scale = scale || new FloatNode( 1 ); this.toNormalMap = false; - -}; -BumpMapNode.Nodes = (function() { - +} + +BumpMapNode.Nodes = ( function () { + var dHdxy_fwd = new FunctionNode( [ // Bump Mapping Unparametrized Surfaces on the GPU by Morten S. Mikkelsen // http://api.unrealengine.com/attachments/Engine/Rendering/LightingAndShadows/BumpMappingWithoutTangentSpace/mm_sfgrad_bump.pdf - + // Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2) "vec2 dHdxy_fwd( sampler2D bumpMap, vec2 vUv, float bumpScale ) {", // Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988 - + " vec2 dSTdx = dFdx( vUv );", " vec2 dSTdy = dFdy( vUv );", - + " float Hll = bumpScale * texture2D( bumpMap, vUv ).x;", " float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;", " float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;", - + " return vec2( dBx, dBy );", - + "}" ].join( "\n" ), null, { derivatives: true } ); @@ -50,20 +50,20 @@ BumpMapNode.Nodes = (function() { "vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {", // Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988 - + " vec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );", " vec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );", " vec3 vN = surf_norm;", // normalized - + " vec3 R1 = cross( vSigmaY, vN );", " vec3 R2 = cross( vN, vSigmaX );", " float fDet = dot( vSigmaX, R1 );", - + " fDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );", - + " vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );", - + " return normalize( abs( fDet ) * surf_norm - vGrad );", "}" @@ -72,26 +72,26 @@ BumpMapNode.Nodes = (function() { var bumpToNormal = new FunctionNode( [ "vec3 bumpToNormal( sampler2D bumpMap, vec2 uv, float scale ) {", - + " vec2 dSTdx = dFdx( uv );", " vec2 dSTdy = dFdy( uv );", - + " float Hll = texture2D( bumpMap, uv ).x;", " float dBx = texture2D( bumpMap, uv + dSTdx ).x - Hll;", " float dBy = texture2D( bumpMap, uv + dSTdy ).x - Hll;", - + " return vec3( .5 - ( dBx * scale ), .5 - ( dBy * scale ), 1.0 );", - + "}" ].join( "\n" ), null, { derivatives: true } ); - + return { dHdxy_fwd: dHdxy_fwd, perturbNormalArb: perturbNormalArb, bumpToNormal: bumpToNormal }; - -})(); + +} )(); BumpMapNode.prototype = Object.create( TempNode.prototype ); BumpMapNode.prototype.constructor = BumpMapNode; @@ -102,21 +102,21 @@ BumpMapNode.prototype.generate = function ( builder, output ) { if ( builder.isShader( 'fragment' ) ) { if ( this.toNormalMap ) { - + var bumpToNormal = builder.include( BumpMapNode.Nodes.bumpToNormal ); - + return builder.format( bumpToNormal + '( ' + this.value.build( builder, 'sampler2D' ) + ', ' + this.value.uv.build( builder, 'v2' ) + ', ' + this.scale.build( builder, 'f' ) + ' )', this.getType( builder ), output ); - + } else { - + var derivativeHeight = builder.include( BumpMapNode.Nodes.dHdxy_fwd ), perturbNormalArb = builder.include( BumpMapNode.Nodes.perturbNormalArb ); - - this.normal = this.normal || new NormalNode( NormalNode.VIEW ); + + this.normal = this.normal || new NormalNode(); this.position = this.position || new PositionNode( PositionNode.VIEW ); - + var derivativeHeightCode = derivativeHeight + '( ' + this.value.build( builder, 'sampler2D' ) + ', ' + this.value.uv.build( builder, 'v2' ) + ', ' + this.scale.build( builder, 'f' ) + ' )'; @@ -124,7 +124,7 @@ BumpMapNode.prototype.generate = function ( builder, output ) { return builder.format( perturbNormalArb + '( -' + this.position.build( builder, 'v3' ) + ', ' + this.normal.build( builder, 'v3' ) + ', ' + derivativeHeightCode + ' )', this.getType( builder ), output ); - + } } else { @@ -138,12 +138,12 @@ BumpMapNode.prototype.generate = function ( builder, output ) { }; BumpMapNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.value = source.value; this.scale = source.scale; - + }; BumpMapNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/misc/NormalMapNode.js b/examples/js/nodes/misc/NormalMapNode.js index 8d33eaa52a9e68fbb63f5246f2e691808878fd50..261d15a2d6d074b90d63fc21c608c7cfbb4b980f 100644 --- a/examples/js/nodes/misc/NormalMapNode.js +++ b/examples/js/nodes/misc/NormalMapNode.js @@ -16,10 +16,10 @@ function NormalMapNode( value, scale ) { this.value = value; this.scale = scale || new Vector2Node( 1, 1 ); -}; +} + +NormalMapNode.Nodes = ( function () { -NormalMapNode.Nodes = (function() { - var perturbNormal2Arb = new FunctionNode( [ // Per-Pixel Tangent Space Normal Mapping @@ -28,24 +28,24 @@ NormalMapNode.Nodes = (function() { "vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 map, vec2 mUv, vec2 normalScale ) {", // Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988 - + " vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );", " vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );", " vec2 st0 = dFdx( mUv.st );", " vec2 st1 = dFdy( mUv.st );", - + " float scale = sign( st1.t * st0.s - st0.t * st1.s );", // we do not care about the magnitude - + " vec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );", " vec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );", " vec3 N = normalize( surf_norm );", " mat3 tsn = mat3( S, T, N );", - + " vec3 mapN = map * 2.0 - 1.0;", - + " mapN.xy *= normalScale;", " mapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );", - + " return normalize( tsn * mapN );", "}" @@ -55,8 +55,8 @@ NormalMapNode.Nodes = (function() { return { perturbNormal2Arb: perturbNormal2Arb }; - -})(); + +} )(); NormalMapNode.prototype = Object.create( TempNode.prototype ); NormalMapNode.prototype.constructor = NormalMapNode; @@ -68,7 +68,7 @@ NormalMapNode.prototype.generate = function ( builder, output ) { var perturbNormal2Arb = builder.include( NormalMapNode.Nodes.perturbNormal2Arb ); - this.normal = this.normal || new NormalNode( NormalNode.VIEW ); + this.normal = this.normal || new NormalNode(); this.position = this.position || new PositionNode( PositionNode.VIEW ); this.uv = this.uv || new UVNode(); @@ -89,12 +89,12 @@ NormalMapNode.prototype.generate = function ( builder, output ) { }; NormalMapNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.value = source.value; this.scale = source.scale; - + }; NormalMapNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/misc/TextureCubeNode.js b/examples/js/nodes/misc/TextureCubeNode.js index 13348dd2ad04f233315cec93a159bce00128e65f..0d900201688f72f189efd57ec16f9e7289675c43 100644 --- a/examples/js/nodes/misc/TextureCubeNode.js +++ b/examples/js/nodes/misc/TextureCubeNode.js @@ -4,7 +4,7 @@ import { TempNode } from '../core/TempNode.js'; import { TextureCubeUVNode } from './TextureCubeUVNode.js'; - + function TextureCubeNode( value, uv ) { TempNode.call( this, 'v4' ); @@ -12,7 +12,7 @@ function TextureCubeNode( value, uv ) { this.value = value; this.uv = uv || new TextureCubeUVNode(); -}; +} TextureCubeNode.prototype = Object.create( TempNode.prototype ); TextureCubeNode.prototype.constructor = TextureCubeNode; @@ -25,12 +25,12 @@ TextureCubeNode.prototype.generate = function ( builder, output ) { var uv_10 = this.uv.build( builder ) + '.uv_10', uv_20 = this.uv.build( builder ) + '.uv_20', t = this.uv.build( builder ) + '.t'; - + var color10 = builder.getTexelDecodingFunctionFromTexture( 'texture2D( ' + this.value.build( builder, 'sampler2D' ) + ', ' + uv_10 + ' )', this.value.value ), color20 = builder.getTexelDecodingFunctionFromTexture( 'texture2D( ' + this.value.build( builder, 'sampler2D' ) + ', ' + uv_20 + ' )', this.value.value ); return builder.format( 'vec4( mix( ' + color10 + ', ' + color20 + ', ' + t + ' ).rgb, 1.0 )', this.getType( builder ), output ); - + } else { console.warn( "THREE.TextureCubeNode is not compatible with " + builder.shader + " shader." ); diff --git a/examples/js/nodes/misc/TextureCubeUVNode.js b/examples/js/nodes/misc/TextureCubeUVNode.js index 0bd261889bbaf39a5b36b72c43d12567b339e628..e4f98189f819e82d8b8b36a72bc29afbdfbad6de 100644 --- a/examples/js/nodes/misc/TextureCubeUVNode.js +++ b/examples/js/nodes/misc/TextureCubeUVNode.js @@ -9,27 +9,27 @@ import { FunctionNode } from '../core/FunctionNode.js'; import { ReflectNode } from '../accessors/ReflectNode.js'; import { FloatNode } from '../inputs/FloatNode.js'; import { BlinnExponentToRoughnessNode } from '../bsdfs/BlinnExponentToRoughnessNode.js'; - + function TextureCubeUVNode( uv, textureSize, blinnExponentToRoughness ) { TempNode.call( this, 'TextureCubeUVData' ); // TextureCubeUVData is type as StructNode this.uv = uv || new ReflectNode( ReflectNode.VECTOR ); this.textureSize = textureSize || new FloatNode( 1024 ); - this.blinnExponentToRoughness = this.blinnExponentToRoughness || new BlinnExponentToRoughnessNode(); + this.blinnExponentToRoughness = blinnExponentToRoughness || new BlinnExponentToRoughnessNode(); -}; +} -TextureCubeUVNode.Nodes = (function() { +TextureCubeUVNode.Nodes = ( function () { - var TextureCubeUVData = new StructNode([ + var TextureCubeUVData = new StructNode( [ "struct TextureCubeUVData {", " vec2 uv_10;", " vec2 uv_20;", " float t;", "}" - ].join( "\n" )); - + ].join( "\n" ) ); + var getFaceFromDirection = new FunctionNode( [ "int getFaceFromDirection(vec3 direction) {", " vec3 absDirection = abs(direction);", @@ -49,10 +49,10 @@ TextureCubeUVNode.Nodes = (function() { " return face;", "}" ].join( "\n" ) ); - + var cubeUV_maxLods1 = new ConstNode( "#define cubeUV_maxLods1 ( log2( cubeUV_textureSize * 0.25 ) - 1.0 )" ); var cubeUV_rangeClamp = new ConstNode( "#define cubeUV_rangeClamp ( exp2( ( 6.0 - 1.0 ) * 2.0 ) )" ); - + var MipLevelInfo = new FunctionNode( [ "vec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness, in float cubeUV_textureSize ) {", " float scale = exp2(cubeUV_maxLods1 - roughnessLevel);", @@ -61,13 +61,13 @@ TextureCubeUVNode.Nodes = (function() { " vec3 dx = dFdx( vec * scale * dxRoughness );", " vec3 dy = dFdy( vec * scale * dyRoughness );", " float d = max( dot( dx, dx ), dot( dy, dy ) );", - // Clamp the value to the max mip level counts. hard coded to 6 mips" + // Clamp the value to the max mip level counts. hard coded to 6 mips" " d = clamp(d, 1.0, cubeUV_rangeClamp);", " float mipLevel = 0.5 * log2(d);", " return vec2(floor(mipLevel), fract(mipLevel));", - "}" + "}" ].join( "\n" ), [ cubeUV_maxLods1, cubeUV_rangeClamp ], { derivatives: true } ); - + var cubeUV_maxLods2 = new ConstNode( "#define cubeUV_maxLods2 ( log2( cubeUV_textureSize * 0.25 ) - 2.0 )" ); var cubeUV_rcpTextureSize = new ConstNode( "#define cubeUV_rcpTextureSize ( 1.0 / cubeUV_textureSize )" ); @@ -78,11 +78,11 @@ TextureCubeUVNode.Nodes = (function() { "", " vec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );", " vec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;", - // float powScale = exp2(roughnessLevel + mipLevel);" + // float powScale = exp2(roughnessLevel + mipLevel);" " float powScale = exp2_packed.x * exp2_packed.y;", - // float scale = 1.0 / exp2(roughnessLevel + 2.0 + mipLevel);" + // float scale = 1.0 / exp2(roughnessLevel + 2.0 + mipLevel);" " float scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;", - // float mipOffset = 0.75*(1.0 - 1.0/exp2(mipLevel))/exp2(roughnessLevel);" + // float mipOffset = 0.75*(1.0 - 1.0/exp2(mipLevel))/exp2(roughnessLevel);" " float mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;", "", " bool bRes = mipLevel == 0.0;", @@ -129,11 +129,11 @@ TextureCubeUVNode.Nodes = (function() { " vec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;", " vec2 base = offset + vec2( texelOffset );", " return base + s * ( scale - 2.0 * texelOffset );", - "}" + "}" ].join( "\n" ), [ cubeUV_maxLods2, cubeUV_rcpTextureSize, getFaceFromDirection ] ); - + var cubeUV_maxLods3 = new ConstNode( "#define cubeUV_maxLods3 ( log2( cubeUV_textureSize * 0.25 ) - 3.0 )" ); - + var textureCubeUV = new FunctionNode( [ "TextureCubeUVData textureCubeUV( vec3 reflectedDirection, float roughness, in float cubeUV_textureSize ) {", " float roughnessVal = roughness * cubeUV_maxLods3;", @@ -146,23 +146,23 @@ TextureCubeUVNode.Nodes = (function() { " float level1 = level0 + 1.0;", " level1 = level1 > 5.0 ? 5.0 : level1;", "", - // round to nearest mipmap if we are not interpolating." + // round to nearest mipmap if we are not interpolating." " level0 += min( floor( s + 0.5 ), 5.0 );", "", - // Tri linear interpolation." + // Tri linear interpolation." " vec2 uv_10 = getCubeUV(reflectedDirection, r1, level0, cubeUV_textureSize);", " vec2 uv_20 = getCubeUV(reflectedDirection, r2, level0, cubeUV_textureSize);", "", " return TextureCubeUVData(uv_10, uv_20, t);", - "}" + "}" ].join( "\n" ), [ TextureCubeUVData, cubeUV_maxLods3, MipLevelInfo, getCubeUV ] ); - + return { TextureCubeUVData: TextureCubeUVData, textureCubeUV: textureCubeUV }; - -})(); + +} )(); TextureCubeUVNode.prototype = Object.create( TempNode.prototype ); TextureCubeUVNode.prototype.constructor = TextureCubeUVNode; @@ -173,11 +173,11 @@ TextureCubeUVNode.prototype.generate = function ( builder, output ) { if ( builder.isShader( 'fragment' ) ) { var textureCubeUV = builder.include( TextureCubeUVNode.Nodes.textureCubeUV ); - + return builder.format( textureCubeUV + '( ' + this.uv.build( builder, 'v3' ) + ', ' + this.blinnExponentToRoughness.build( builder, 'f' ) + ', ' + this.textureSize.build( builder, 'f' ) + ' )', this.getType( builder ), output ); - + } else { console.warn( "THREE.TextureCubeUVNode is not compatible with " + builder.shader + " shader." ); diff --git a/examples/js/nodes/postprocessing/NodePass.js b/examples/js/nodes/postprocessing/NodePass.js index 20d5775b47abbbec8b14efbe40fab56ae54c6e59..f92a2a817edce46c9170b864c38336e00d1780da 100644 --- a/examples/js/nodes/postprocessing/NodePass.js +++ b/examples/js/nodes/postprocessing/NodePass.js @@ -2,9 +2,7 @@ * @author sunag / http://www.sunag.com.br/ */ -import { NodeUtils } from '../core/NodeUtils.js'; import { NodeMaterial } from '../materials/NodeMaterial.js'; -import { RawNode } from '../materials/nodes/RawNode.js'; import { ScreenNode } from '../inputs/ScreenNode.js'; function NodePass() { @@ -18,41 +16,39 @@ function NodePass() { this.textureID = 'renderTexture'; - this.fragment = new RawNode( new ScreenNode() ); + this.input = new ScreenNode(); - this.node = new NodeMaterial(); - this.node.fragment = this.fragment; + this.material = new NodeMaterial(); this.needsUpdate = true; -}; +} NodePass.prototype = Object.create( THREE.ShaderPass.prototype ); NodePass.prototype.constructor = NodePass; -NodeUtils.addShortcuts( NodePass.prototype, 'fragment', [ 'value' ] ); - NodePass.prototype.render = function () { if ( this.needsUpdate ) { - this.node.dispose(); + this.material.dispose(); + + this.material.fragment.value = this.input; this.needsUpdate = false; } - this.uniforms = this.node.uniforms; - this.material = this.node; + this.uniforms = this.material.uniforms; THREE.ShaderPass.prototype.render.apply( this, arguments ); }; NodePass.prototype.copy = function ( source ) { - - this.value = source.value; - + + this.input = source.input; + }; NodePass.prototype.toJSON = function ( meta ) { @@ -82,7 +78,7 @@ NodePass.prototype.toJSON = function ( meta ) { if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData; - data.value = this.value.toJSON( meta ).uuid; + data.input = this.input.toJSON( meta ).uuid; } diff --git a/examples/js/nodes/postprocessing/NodePostProcessing.js b/examples/js/nodes/postprocessing/NodePostProcessing.js new file mode 100644 index 0000000000000000000000000000000000000000..cc24ba1d0fa88f0da15e4dd921f2f63bb6712e00 --- /dev/null +++ b/examples/js/nodes/postprocessing/NodePostProcessing.js @@ -0,0 +1,128 @@ +/** + * @author sunag / http://www.sunag.com.br/ + */ + +import { NodeMaterial } from '../materials/NodeMaterial.js'; +import { ScreenNode } from '../inputs/ScreenNode.js'; + +function NodePostProcessing( renderer, renderTarget ) { + + if ( renderTarget === undefined ) { + + var parameters = { + minFilter: THREE.LinearFilter, + magFilter: THREE.LinearFilter, + format: THREE.RGBAFormat, + stencilBuffer: false + }; + + var size = renderer.getDrawingBufferSize(); + renderTarget = new THREE.WebGLRenderTarget( size.width, size.height, parameters ); + + } + + this.renderer = renderer; + this.renderTarget = renderTarget; + + this.output = new ScreenNode(); + this.material = new NodeMaterial(); + + this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); + this.scene = new THREE.Scene(); + + this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), this.material ); + this.quad.frustumCulled = false; // Avoid getting clipped + this.scene.add( this.quad ); + + this.needsUpdate = true; + +} + +NodePostProcessing.prototype = { + + constructor: NodePostProcessing, + + render: function ( scene, camera, frame ) { + + if ( this.needsUpdate ) { + + this.material.dispose(); + + this.material.fragment.value = this.output; + this.material.build(); + + if ( this.material.uniforms.renderTexture ) { + + this.material.uniforms.renderTexture.value = this.renderTarget.texture; + + } + + this.needsUpdate = false; + + } + + frame.setRenderer( this.renderer ) + .setRenderTexture( this.renderTarget.texture ); + + this.renderer.render( scene, camera, this.renderTarget ); + + frame.updateNode( this.material ); + + this.renderer.render( this.scene, this.camera ); + + }, + + setSize: function ( width, height ) { + + this.renderTarget.setSize( width, height ); + + this.renderer.setSize( width, height ); + + }, + + copy: function ( source ) { + + this.output = source.output; + + }, + + toJSON: function ( meta ) { + + var isRootObject = ( meta === undefined || typeof meta === 'string' ); + + if ( isRootObject ) { + + meta = { + nodes: {} + }; + + } + + if ( meta && ! meta.post ) meta.post = {}; + + if ( ! meta.post[ this.uuid ] ) { + + var data = {}; + + data.uuid = this.uuid; + data.type = "NodePostProcessing"; + + meta.post[ this.uuid ] = data; + + if ( this.name !== "" ) data.name = this.name; + + if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData; + + data.output = this.output.toJSON( meta ).uuid; + + } + + meta.post = this.uuid; + + return meta; + + } + +}; + +export { NodePostProcessing }; diff --git a/examples/js/nodes/procedural/CheckerNode.js b/examples/js/nodes/procedural/CheckerNode.js new file mode 100644 index 0000000000000000000000000000000000000000..42d1b84ff21cdeeb7af1b5f9bc803bd6bf5b6005 --- /dev/null +++ b/examples/js/nodes/procedural/CheckerNode.js @@ -0,0 +1,75 @@ +/** + * @author sunag / http://www.sunag.com.br/ + */ + +import { TempNode } from '../core/TempNode.js'; +import { FunctionNode } from '../core/FunctionNode.js'; +import { UVNode } from '../accessors/UVNode.js'; + +function CheckerNode( uv ) { + + TempNode.call( this, 'f' ); + + this.uv = uv || new UVNode(); + +} + +CheckerNode.prototype = Object.create( TempNode.prototype ); +CheckerNode.prototype.constructor = CheckerNode; +CheckerNode.prototype.nodeType = "Noise"; + +CheckerNode.Nodes = ( function () { + + // https://github.com/mattdesl/glsl-checker/blob/master/index.glsl + + var checker = new FunctionNode( [ + "float checker( vec2 uv ) {", + + " float cx = floor( uv.x );", + " float cy = floor( uv.y ); ", + " float result = mod( cx + cy, 2.0 );", + + " return sign( result );", + + "}" + ].join( "\n" ) ); + + return { + checker: checker + }; + +} )(); + +CheckerNode.prototype.generate = function ( builder, output ) { + + var snoise = builder.include( CheckerNode.Nodes.checker ); + + return builder.format( snoise + '( ' + this.uv.build( builder, 'v2' ) + ' )', this.getType( builder ), output ); + +}; + +CheckerNode.prototype.copy = function ( source ) { + + TempNode.prototype.copy.call( this, source ); + + this.uv = source.uv; + +}; + +CheckerNode.prototype.toJSON = function ( meta ) { + + var data = this.getJSONNode( meta ); + + if ( ! data ) { + + data = this.createJSONNode( meta ); + + data.uv = this.uv.toJSON( meta ).uuid; + + } + + return data; + +}; + +export { CheckerNode }; diff --git a/examples/js/nodes/procedural/NoiseNode.js b/examples/js/nodes/procedural/NoiseNode.js index 81d350928a927060a76176f285e7241a5b061ce3..e743febdb402741be1fe04e134180b300c30929e 100644 --- a/examples/js/nodes/procedural/NoiseNode.js +++ b/examples/js/nodes/procedural/NoiseNode.js @@ -12,27 +12,27 @@ function NoiseNode( uv ) { this.uv = uv || new UVNode(); -}; +} NoiseNode.prototype = Object.create( TempNode.prototype ); NoiseNode.prototype.constructor = NoiseNode; NoiseNode.prototype.nodeType = "Noise"; -NoiseNode.Nodes = (function() { - +NoiseNode.Nodes = ( function () { + var snoise = new FunctionNode( [ "float snoise(vec2 co) {", - + " return fract( sin( dot( co.xy, vec2( 12.9898, 78.233 ) ) ) * 43758.5453 );", - + "}" ].join( "\n" ) ); return { snoise: snoise }; - -})(); + +} )(); NoiseNode.prototype.generate = function ( builder, output ) { @@ -43,11 +43,11 @@ NoiseNode.prototype.generate = function ( builder, output ) { }; NoiseNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + this.uv = source.uv; - + }; NoiseNode.prototype.toJSON = function ( meta ) { @@ -66,4 +66,4 @@ NoiseNode.prototype.toJSON = function ( meta ) { }; -export { NoiseNode }; \ No newline at end of file +export { NoiseNode }; diff --git a/examples/js/nodes/utils/BypassNode.js b/examples/js/nodes/utils/BypassNode.js index cc32ab2242ac70526ee52260981c7277d2fd7ffe..bc671933c32935a1a99f5305a110b2a4cbaab865 100644 --- a/examples/js/nodes/utils/BypassNode.js +++ b/examples/js/nodes/utils/BypassNode.js @@ -2,33 +2,33 @@ * @author sunag / http://www.sunag.com.br/ */ -import { GLNode } from '../core/GLNode.js'; +import { Node } from '../core/Node.js'; function BypassNode( code, value ) { - GLNode.call( this ); + Node.call( this ); this.code = code; this.value = value; -}; +} -BypassNode.prototype = Object.create( GLNode.prototype ); +BypassNode.prototype = Object.create( Node.prototype ); BypassNode.prototype.constructor = BypassNode; BypassNode.prototype.nodeType = "Bypass"; BypassNode.prototype.getType = function ( builder ) { if ( this.value ) { - + return this.value.getType( builder ); - - } else if (builder.isShader( 'fragment' )) { - + + } else if ( builder.isShader( 'fragment' ) ) { + return 'f'; - + } - + return 'void'; }; @@ -38,30 +38,30 @@ BypassNode.prototype.generate = function ( builder, output ) { var code = this.code.build( builder, output ) + ';'; builder.addNodeCode( code ); - + if ( builder.isShader( 'vertex' ) ) { - - if (this.value) { - + + if ( this.value ) { + return this.value.build( builder, output ); - + } - + } else { - + return this.value ? this.value.build( builder, output ) : builder.format( '0.0', 'f', output ); - + } }; BypassNode.prototype.copy = function ( source ) { - - GLNode.prototype.copy.call( this, source ); - + + Node.prototype.copy.call( this, source ); + this.code = source.code; this.value = source.value; - + }; BypassNode.prototype.toJSON = function ( meta ) { @@ -74,7 +74,7 @@ BypassNode.prototype.toJSON = function ( meta ) { data.code = this.code.toJSON( meta ).uuid; - if (this.value) data.value = this.value.toJSON( meta ).uuid; + if ( this.value ) data.value = this.value.toJSON( meta ).uuid; } diff --git a/examples/js/nodes/utils/ColorSpaceNode.js b/examples/js/nodes/utils/ColorSpaceNode.js new file mode 100644 index 0000000000000000000000000000000000000000..44572735140baf8b0ccd4d84dc58fc1f1c46fd64 --- /dev/null +++ b/examples/js/nodes/utils/ColorSpaceNode.js @@ -0,0 +1,297 @@ +/** + * @author sunag / http://www.sunag.com.br/ + */ + +import { TempNode } from '../core/TempNode.js'; +import { ConstNode } from '../core/ConstNode.js'; +import { FunctionNode } from '../core/FunctionNode.js'; + +function ColorSpaceNode( input, method ) { + + TempNode.call( this, 'v4' ); + + this.input = input; + + this.method = method || ColorSpaceNode.LINEAR; + +} + +ColorSpaceNode.Nodes = ( function () { + + // For a discussion of what this is, please read this: http://lousodrome.net/blog/light/2013/05/26/gamma-correct-and-hdr-rendering-in-a-32-bits-buffer/ + + var LinearToLinear = new FunctionNode( [ + "vec4 LinearToLinear( in vec4 value ) {", + + " return value;", + + "}" + ].join( "\n" ) ); + + var GammaToLinear = new FunctionNode( [ + "vec4 GammaToLinear( in vec4 value, in float gammaFactor ) {", + + " return vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );", + + "}" + ].join( "\n" ) ); + + var LinearToGamma = new FunctionNode( [ + "vec4 LinearToGamma( in vec4 value, in float gammaFactor ) {", + + " return vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );", + + "}" + ].join( "\n" ) ); + + var sRGBToLinear = new FunctionNode( [ + "vec4 sRGBToLinear( in vec4 value ) {", + + " return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );", + + "}" + ].join( "\n" ) ); + + var LinearTosRGB = new FunctionNode( [ + "vec4 LinearTosRGB( in vec4 value ) {", + + " return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );", + + "}" + ].join( "\n" ) ); + + var RGBEToLinear = new FunctionNode( [ + "vec4 RGBEToLinear( in vec4 value ) {", + + " return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );", + + "}" + ].join( "\n" ) ); + + var LinearToRGBE = new FunctionNode( [ + "vec4 LinearToRGBE( in vec4 value ) {", + + " float maxComponent = max( max( value.r, value.g ), value.b );", + " float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );", + " return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );", + // return vec4( value.brg, ( 3.0 + 128.0 ) / 256.0 ); + + "}" + ].join( "\n" ) ); + + // reference: http://iwasbeingirony.blogspot.ca/2010/06/difference-between-rgbm-and-rgbd.html + + var RGBMToLinear = new FunctionNode( [ + "vec3 RGBMToLinear( in vec4 value, in float maxRange ) {", + + " return vec4( value.xyz * value.w * maxRange, 1.0 );", + + "}" + ].join( "\n" ) ); + + var LinearToRGBM = new FunctionNode( [ + "vec3 LinearToRGBM( in vec4 value, in float maxRange ) {", + + " float maxRGB = max( value.x, max( value.g, value.b ) );", + " float M = clamp( maxRGB / maxRange, 0.0, 1.0 );", + " M = ceil( M * 255.0 ) / 255.0;", + " return vec4( value.rgb / ( M * maxRange ), M );", + + "}" + ].join( "\n" ) ); + + // reference: http://iwasbeingirony.blogspot.ca/2010/06/difference-between-rgbm-and-rgbd.html + + var RGBDToLinear = new FunctionNode( [ + "vec3 RGBDToLinear( in vec4 value, in float maxRange ) {", + + " return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );", + + "}" + ].join( "\n" ) ); + + + var LinearToRGBD = new FunctionNode( [ + "vec3 LinearToRGBD( in vec4 value, in float maxRange ) {", + + " float maxRGB = max( value.x, max( value.g, value.b ) );", + " float D = max( maxRange / maxRGB, 1.0 );", + " D = min( floor( D ) / 255.0, 1.0 );", + " return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );", + + "}" + ].join( "\n" ) ); + + // LogLuv reference: http://graphicrants.blogspot.ca/2009/04/rgbm-color-encoding.html + + // M matrix, for encoding + + var cLogLuvM = new ConstNode( "const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );" ); + + var LinearToLogLuv = new FunctionNode( [ + "vec4 LinearToLogLuv( in vec4 value ) {", + + " vec3 Xp_Y_XYZp = value.rgb * cLogLuvM;", + " Xp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));", + " vec4 vResult;", + " vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;", + " float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;", + " vResult.w = fract(Le);", + " vResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;", + " return vResult;", + + "}" + ].join( "\n" ), [ cLogLuvM ] ); + + // Inverse M matrix, for decoding + + var cLogLuvInverseM = new ConstNode( "const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );" ); + + var LogLuvToLinear = new FunctionNode( [ + "vec4 LogLuvToLinear( in vec4 value ) {", + + " float Le = value.z * 255.0 + value.w;", + " vec3 Xp_Y_XYZp;", + " Xp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);", + " Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;", + " Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;", + " vec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;", + " return vec4( max(vRGB, 0.0), 1.0 );", + + "}" + ].join( "\n" ), [ cLogLuvInverseM ] ); + + return { + LinearToLinear: LinearToLinear, + GammaToLinear: GammaToLinear, + LinearToGamma: LinearToGamma, + sRGBToLinear: sRGBToLinear, + LinearTosRGB: LinearTosRGB, + RGBEToLinear: RGBEToLinear, + LinearToRGBE: LinearToRGBE, + RGBMToLinear: RGBMToLinear, + LinearToRGBM: LinearToRGBM, + RGBDToLinear: RGBDToLinear, + LinearToRGBD: LinearToRGBD, + cLogLuvM: cLogLuvM, + LinearToLogLuv: LinearToLogLuv, + cLogLuvInverseM: cLogLuvInverseM, + LogLuvToLinear: LogLuvToLinear + }; + +} )(); + +ColorSpaceNode.LINEAR_TO_LINEAR = 'LinearToLinear'; + +ColorSpaceNode.GAMMA_TO_LINEAR = 'GammaToLinear'; +ColorSpaceNode.LINEAR_TO_GAMMA = 'LinearToGamma'; + +ColorSpaceNode.SRGB_TO_LINEAR = 'sRGBToLinear'; +ColorSpaceNode.LINEAR_TO_SRGB = 'LinearTosRGB'; + +ColorSpaceNode.RGBE_TO_LINEAR = 'RGBEToLinear'; +ColorSpaceNode.LINEAR_TO_RGBE = 'LinearToRGBE'; + +ColorSpaceNode.RGBM_TO_LINEAR = 'RGBMToLinear'; +ColorSpaceNode.LINEAR_TO_RGBM = 'LinearToRGBM'; + +ColorSpaceNode.RGBD_TO_LINEAR = 'RGBDToLinear'; +ColorSpaceNode.LINEAR_TO_RGBD = 'LinearToRGBD'; + +ColorSpaceNode.LINEAR_TO_LOG_LUV = 'LinearToLogLuv'; +ColorSpaceNode.LOG_LUV_TO_LINEAR = 'LogLuvToLinear'; + +ColorSpaceNode.prototype = Object.create( TempNode.prototype ); +ColorSpaceNode.prototype.constructor = ColorSpaceNode; +ColorSpaceNode.prototype.nodeType = "ColorAdjustment"; + +ColorSpaceNode.prototype.generate = function ( builder, output ) { + + var input = builder.context.input || this.input.build( builder, 'v4' ), + encodingMethod = builder.context.encoding !== undefined ? this.getEncodingMethod( builder.context.encoding ) : [ this.method ], + factor = this.factor ? this.factor.build( builder, 'f' ) : encodingMethod[ 1 ]; + + var method = builder.include( ColorSpaceNode.Nodes[ encodingMethod[ 0 ] ] ); + + if ( factor ) { + + return builder.format( method + '( ' + input + ', ' + factor + ' )', this.getType( builder ), output ); + + } else { + + return builder.format( method + '( ' + input + ' )', this.getType( builder ), output ); + + } + +}; + +ColorSpaceNode.prototype.getDecodingMethod = function ( encoding ) { + + var components = this.getEncodingComponents( encoding ); + + components[ 0 ] += 'ToLinear'; + + return components; + +}; + +ColorSpaceNode.prototype.getEncodingMethod = function ( encoding ) { + + var components = this.getEncodingComponents( encoding ); + + components[ 0 ] = 'LinearTo' + components[ 0 ]; + + return components; + +}; + +ColorSpaceNode.prototype.getEncodingComponents = function ( encoding ) { + + switch ( encoding ) { + + case THREE.LinearEncoding: + return [ 'Linear' ]; + case THREE.sRGBEncoding: + return [ 'sRGB' ]; + case THREE.RGBEEncoding: + return [ 'RGBE' ]; + case THREE.RGBM7Encoding: + return [ 'RGBM', '7.0' ]; + case THREE.RGBM16Encoding: + return [ 'RGBM', '16.0' ]; + case THREE.RGBDEncoding: + return [ 'RGBD', '256.0' ]; + case THREE.GammaEncoding: + return [ 'Gamma', 'float( GAMMA_FACTOR )' ]; + + } + +}; + +ColorSpaceNode.prototype.copy = function ( source ) { + + TempNode.prototype.copy.call( this, source ); + + this.input = source.input; + this.method = source.method; + +}; + +ColorSpaceNode.prototype.toJSON = function ( meta ) { + + var data = this.getJSONNode( meta ); + + if ( ! data ) { + + data = this.createJSONNode( meta ); + + data.input = this.input.toJSON( meta ).uuid; + data.method = this.method; + + } + + return data; + +}; + +export { ColorSpaceNode }; diff --git a/examples/js/nodes/utils/JoinNode.js b/examples/js/nodes/utils/JoinNode.js index 6ebd7d9d78df441bb2ba39f4ce9a29fe1591fff1..b3d4ca2b1d97b591ae5370c61e3190ea5f9a967c 100644 --- a/examples/js/nodes/utils/JoinNode.js +++ b/examples/js/nodes/utils/JoinNode.js @@ -4,9 +4,9 @@ import { TempNode } from '../core/TempNode.js'; import { NodeUtils } from '../core/NodeUtils.js'; - + var inputs = NodeUtils.elements; - + function JoinNode( x, y, z, w ) { TempNode.call( this, 'f' ); @@ -16,7 +16,7 @@ function JoinNode( x, y, z, w ) { this.z = z; this.w = w; -}; +} JoinNode.prototype = Object.create( TempNode.prototype ); JoinNode.prototype.constructor = JoinNode; @@ -31,7 +31,7 @@ JoinNode.prototype.getNumElements = function () { if ( this[ inputs[ i ] ] !== undefined ) { ++ i; - + break; } @@ -69,15 +69,15 @@ JoinNode.prototype.generate = function ( builder, output ) { }; JoinNode.prototype.copy = function ( source ) { - + TempNode.prototype.copy.call( this, source ); - + for ( var prop in source.inputs ) { this[ prop ] = source.inputs[ prop ]; } - + }; JoinNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/utils/MaxMIPLevelNode.js b/examples/js/nodes/utils/MaxMIPLevelNode.js index 9784e194b9700d4e0f17616f7b353249463e0a16..7d42fbfa9a9a6630c3116c61bc5338047b47e8f1 100644 --- a/examples/js/nodes/utils/MaxMIPLevelNode.js +++ b/examples/js/nodes/utils/MaxMIPLevelNode.js @@ -3,7 +3,7 @@ */ import { FloatNode } from '../inputs/FloatNode.js'; - + function MaxMIPLevelNode( texture ) { FloatNode.call( this ); @@ -12,7 +12,7 @@ function MaxMIPLevelNode( texture ) { this.maxMIPLevel = 0; -}; +} MaxMIPLevelNode.prototype = Object.create( FloatNode.prototype ); MaxMIPLevelNode.prototype.constructor = MaxMIPLevelNode; @@ -21,23 +21,23 @@ MaxMIPLevelNode.prototype.nodeType = "MaxMIPLevel"; Object.defineProperties( MaxMIPLevelNode.prototype, { value: { - + get: function () { if ( this.maxMIPLevel === 0 ) { - var image = this.texture.value.image ? this.texture.value.image[0] : undefined; + var image = this.texture.value.image ? this.texture.value.image[ 0 ] : undefined; - this.maxMIPLevel = image !== undefined ? ( Math.log( Math.max( image.width, image.height ) ) + 1 ) * Math.LOG2E : 0; + this.maxMIPLevel = image !== undefined ? Math.log( Math.max( image.width, image.height ) ) * Math.LOG2E : 0; } return this.maxMIPLevel; }, - + set: function () { } - + } } ); diff --git a/examples/js/nodes/utils/SwitchNode.js b/examples/js/nodes/utils/SwitchNode.js index 712952c3e4f3e761c11b551fd6c1e1f74942340a..c4b67e964f521bcd84b25ae1bb89bf0b75ec4d2b 100644 --- a/examples/js/nodes/utils/SwitchNode.js +++ b/examples/js/nodes/utils/SwitchNode.js @@ -2,18 +2,18 @@ * @author sunag / http://www.sunag.com.br/ */ -import { GLNode } from '../core/GLNode.js'; - +import { Node } from '../core/Node.js'; + function SwitchNode( node, components ) { - GLNode.call( this ); + Node.call( this ); this.node = node; this.components = components || 'x'; -}; +} -SwitchNode.prototype = Object.create( GLNode.prototype ); +SwitchNode.prototype = Object.create( Node.prototype ); SwitchNode.prototype.constructor = SwitchNode; SwitchNode.prototype.nodeType = "Switch"; @@ -74,12 +74,12 @@ SwitchNode.prototype.generate = function ( builder, output ) { }; SwitchNode.prototype.copy = function ( source ) { - - GLNode.prototype.copy.call( this, source ); - + + Node.prototype.copy.call( this, source ); + this.node = source.node; this.components = source.components; - + }; SwitchNode.prototype.toJSON = function ( meta ) { diff --git a/examples/js/nodes/utils/TimerNode.js b/examples/js/nodes/utils/TimerNode.js index dbaa37d7d69b02f575e1914725fc49b7a879420b..4e8f27d7b035ce91d767f9fab04b05b96c800e71 100644 --- a/examples/js/nodes/utils/TimerNode.js +++ b/examples/js/nodes/utils/TimerNode.js @@ -4,17 +4,17 @@ import { FloatNode } from '../inputs/FloatNode.js'; import { NodeLib } from '../core/NodeLib.js'; - -function TimerNode( scale, scope, useTimeScale ) { + +function TimerNode( scale, scope, timeScale ) { FloatNode.call( this ); this.scale = scale !== undefined ? scale : 1; this.scope = scope || TimerNode.GLOBAL; - this.useTimeScale = useTimeScale !== undefined ? useTimeScale : this.scale !== 1; + this.timeScale = timeScale !== undefined ? timeScale : this.scale !== 1; -}; +} TimerNode.GLOBAL = 'global'; TimerNode.LOCAL = 'local'; @@ -26,6 +26,8 @@ TimerNode.prototype.nodeType = "Timer"; TimerNode.prototype.isReadonly = function () { + // never use TimerNode as readonly but aways as "uniform" + return false; }; @@ -33,6 +35,7 @@ TimerNode.prototype.isReadonly = function () { TimerNode.prototype.isUnique = function () { // share TimerNode "uniform" input if is used on more time with others TimerNode + return this.timeScale && ( this.scope === TimerNode.GLOBAL || this.scope === TimerNode.DELTA ); }; @@ -41,7 +44,7 @@ TimerNode.prototype.updateFrame = function ( frame ) { var scale = this.timeScale ? this.scale : 1; - switch( this.scope ) { + switch ( this.scope ) { case TimerNode.LOCAL: @@ -64,14 +67,14 @@ TimerNode.prototype.updateFrame = function ( frame ) { }; TimerNode.prototype.copy = function ( source ) { - + FloatNode.prototype.copy.call( this, source ); - + this.scope = source.scope; this.scale = source.scale; - - this.useTimeScale = source.useTimeScale; - + + this.timeScale = source.timeScale; + }; TimerNode.prototype.toJSON = function ( meta ) { @@ -84,8 +87,8 @@ TimerNode.prototype.toJSON = function ( meta ) { data.scope = this.scope; data.scale = this.scale; - - data.useTimeScale = this.useTimeScale; + + data.timeScale = this.timeScale; } diff --git a/examples/js/nodes/utils/UVTransformNode.js b/examples/js/nodes/utils/UVTransformNode.js index 1990b29b10bb04add2a032d92eca3ce68b40259c..a19149ad0f059f58fd9023dd29e089974cf48fa5 100644 --- a/examples/js/nodes/utils/UVTransformNode.js +++ b/examples/js/nodes/utils/UVTransformNode.js @@ -2,29 +2,29 @@ * @author sunag / http://www.sunag.com.br/ */ -import { FunctionNode } from '../core/FunctionNode.js'; +import { ExpressionNode } from '../core/ExpressionNode.js'; import { Matrix3Node } from '../inputs/Matrix3Node.js'; import { UVNode } from '../accessors/UVNode.js'; - -function UVTransformNode( uv, transform ) { - FunctionNode.call( this, "( uvTransform * vec3( uvNode, 1 ) ).xy", "vec2" ); +function UVTransformNode( uv, position ) { + + ExpressionNode.call( this, "( uvTransform * vec3( uvNode, 1 ) ).xy", "vec2" ); this.uv = uv || new UVNode(); - this.transform = transform || new Matrix3Node(); + this.position = position || new Matrix3Node(); -}; +} -UVTransformNode.prototype = Object.create( FunctionNode.prototype ); +UVTransformNode.prototype = Object.create( ExpressionNode.prototype ); UVTransformNode.prototype.constructor = UVTransformNode; UVTransformNode.prototype.nodeType = "UVTransform"; UVTransformNode.prototype.generate = function ( builder, output ) { this.keywords[ "uvNode" ] = this.uv; - this.keywords[ "uvTransform" ] = this.transform; + this.keywords[ "uvTransform" ] = this.position; - return FunctionNode.prototype.generate.call( this, builder, output ); + return ExpressionNode.prototype.generate.call( this, builder, output ); }; @@ -33,17 +33,17 @@ UVTransformNode.prototype.setUvTransform = function ( tx, ty, sx, sy, rotation, cx = cx !== undefined ? cx : .5; cy = cy !== undefined ? cy : .5; - this.transform.value.setUvTransform( tx, ty, sx, sy, rotation, cx, cy ); + this.position.value.setUvTransform( tx, ty, sx, sy, rotation, cx, cy ); }; UVTransformNode.prototype.copy = function ( source ) { - - FunctionNode.prototype.copy.call( this, source ); - + + ExpressionNode.prototype.copy.call( this, source ); + this.uv = source.uv; - this.transform = source.transform; - + this.position = source.position; + }; UVTransformNode.prototype.toJSON = function ( meta ) { @@ -55,7 +55,7 @@ UVTransformNode.prototype.toJSON = function ( meta ) { data = this.createJSONNode( meta ); data.uv = this.uv.toJSON( meta ).uuid; - data.transform = this.transform.toJSON( meta ).uuid; + data.position = this.position.toJSON( meta ).uuid; } @@ -63,4 +63,4 @@ UVTransformNode.prototype.toJSON = function ( meta ) { }; -export { UVTransformNode }; \ No newline at end of file +export { UVTransformNode }; diff --git a/examples/js/nodes/utils/VelocityNode.js b/examples/js/nodes/utils/VelocityNode.js index 54af79ca3307531a2dfb14f160fdea3a83920556..69eb79bd0176a86fbcf0ef5731f398b75a29b84e 100644 --- a/examples/js/nodes/utils/VelocityNode.js +++ b/examples/js/nodes/utils/VelocityNode.js @@ -3,7 +3,7 @@ */ import { Vector3Node } from '../inputs/Vector3Node.js'; - + function VelocityNode( target, params ) { Vector3Node.call( this ); @@ -15,7 +15,7 @@ function VelocityNode( target, params ) { this.setTarget( target ); this.setParams( params ); -}; +} VelocityNode.prototype = Object.create( Vector3Node.prototype ); VelocityNode.prototype.constructor = VelocityNode; @@ -143,13 +143,13 @@ VelocityNode.prototype.updateFrame = function ( frame ) { }; VelocityNode.prototype.copy = function ( source ) { - + Vector3Node.prototype.copy.call( this, source ); - + if ( source.target ) object.setTarget( source.target ); - + object.setParams( source.params ); - + }; VelocityNode.prototype.toJSON = function ( meta ) { @@ -171,4 +171,4 @@ VelocityNode.prototype.toJSON = function ( meta ) { }; -export { VelocityNode }; \ No newline at end of file +export { VelocityNode }; diff --git a/examples/nodes/displace.json b/examples/nodes/displace.json index 8240894a29f84f942a441cae1d51df0d1ae42207..458bed55fe611757d35832427f0bbd24dba72333 100644 --- a/examples/nodes/displace.json +++ b/examples/nodes/displace.json @@ -1 +1 @@ -{"nodes":{"A9543A4D-4036-4AB3-AEF1-0AE10CFDD4A6":{"uuid":"A9543A4D-4036-4AB3-AEF1-0AE10CFDD4A6","nodeType":"Phong","transform":"A298C150-1E98-425D-8552-CF4690C3238E","color":"DCD2B815-345D-4600-BAFD-BE26925C60E6","specular":"DCD2B815-345D-4600-BAFD-BE26925C60E6","shininess":"5E1EEAA6-F057-4D5F-8607-E9F8265D2B0A","emissive":"BF320EA1-F523-4314-9B87-07E33F39CC6C"},"A298C150-1E98-425D-8552-CF4690C3238E":{"uuid":"A298C150-1E98-425D-8552-CF4690C3238E","nodeType":"Operator","a":"6449FE7E-56E7-490E-9CA9-9F5E9A540AFD","b":"09ECA9C2-8B78-422B-B3DA-2194BCBC5FCA","op":"+"},"6449FE7E-56E7-490E-9CA9-9F5E9A540AFD":{"uuid":"6449FE7E-56E7-490E-9CA9-9F5E9A540AFD","nodeType":"Position","scope":"local"},"09ECA9C2-8B78-422B-B3DA-2194BCBC5FCA":{"uuid":"09ECA9C2-8B78-422B-B3DA-2194BCBC5FCA","nodeType":"Operator","a":"C4573235-0C78-460A-BB35-E41470304BD5","b":"1FF6B149-BCA7-4F37-91E9-8AFA8770F084","op":"*"},"C4573235-0C78-460A-BB35-E41470304BD5":{"uuid":"C4573235-0C78-460A-BB35-E41470304BD5","nodeType":"Operator","a":"0E355E3B-23AB-4225-9477-312295B18436","b":"ABD03824-B7F8-46A4-9006-03FBA06618A9","op":"*"},"0E355E3B-23AB-4225-9477-312295B18436":{"uuid":"0E355E3B-23AB-4225-9477-312295B18436","nodeType":"Normal","scope":"local"},"ABD03824-B7F8-46A4-9006-03FBA06618A9":{"uuid":"ABD03824-B7F8-46A4-9006-03FBA06618A9","nodeType":"Switch","node":"43D31AB8-1DD6-46BE-8969-0668FAB513E2","components":"w"},"43D31AB8-1DD6-46BE-8969-0668FAB513E2":{"uuid":"43D31AB8-1DD6-46BE-8969-0668FAB513E2","nodeType":"Texture","value":"cloud","uv":"273D729E-E18D-47AE-8299-F069FDB6C43A","project":false},"273D729E-E18D-47AE-8299-F069FDB6C43A":{"uuid":"273D729E-E18D-47AE-8299-F069FDB6C43A","nodeType":"Operator","a":"C46D2A54-57A8-4649-AF9B-09D011AF3BFD","b":"C43B8DA9-AFF5-4690-B2EA-3EED061C0662","op":"+"},"C46D2A54-57A8-4649-AF9B-09D011AF3BFD":{"uuid":"C46D2A54-57A8-4649-AF9B-09D011AF3BFD","nodeType":"Operator","a":"F81EC887-A160-455B-B1DE-A0FA2B7FAC36","b":"801913CD-EC7A-47BE-A54C-3D86020B0847","op":"*"},"F81EC887-A160-455B-B1DE-A0FA2B7FAC36":{"uuid":"F81EC887-A160-455B-B1DE-A0FA2B7FAC36","nodeType":"Timer","name":"time","scope":"global","scale":1,"useTimeScale":false},"801913CD-EC7A-47BE-A54C-3D86020B0847":{"uuid":"801913CD-EC7A-47BE-A54C-3D86020B0847","nodeType":"Float","name":"speed","value":0.2},"C43B8DA9-AFF5-4690-B2EA-3EED061C0662":{"uuid":"C43B8DA9-AFF5-4690-B2EA-3EED061C0662","nodeType":"UV","index":0},"1FF6B149-BCA7-4F37-91E9-8AFA8770F084":{"uuid":"1FF6B149-BCA7-4F37-91E9-8AFA8770F084","nodeType":"Float","value":2},"DCD2B815-345D-4600-BAFD-BE26925C60E6":{"uuid":"DCD2B815-345D-4600-BAFD-BE26925C60E6","nodeType":"Color","r":0,"g":0,"b":0},"5E1EEAA6-F057-4D5F-8607-E9F8265D2B0A":{"uuid":"5E1EEAA6-F057-4D5F-8607-E9F8265D2B0A","nodeType":"Float","value":30},"BF320EA1-F523-4314-9B87-07E33F39CC6C":{"uuid":"BF320EA1-F523-4314-9B87-07E33F39CC6C","nodeType":"Math3","a":"F9EA5DC0-2BC8-4C38-A480-1DA3D0680AAE","b":"65010573-EE24-42A3-B32C-3945F3CF2E93","c":"ABD03824-B7F8-46A4-9006-03FBA06618A9","method":"mix"},"F9EA5DC0-2BC8-4C38-A480-1DA3D0680AAE":{"uuid":"F9EA5DC0-2BC8-4C38-A480-1DA3D0680AAE","nodeType":"Color","r":0,"g":0.32941176470588235,"b":0.8745098039215686},"65010573-EE24-42A3-B32C-3945F3CF2E93":{"uuid":"65010573-EE24-42A3-B32C-3945F3CF2E93","nodeType":"Color","r":1,"g":1,"b":1}},"materials":{"BCB86F69-822F-4F9C-838B-70F657904D05":{"uuid":"BCB86F69-822F-4F9C-838B-70F657904D05","type":"PhongNodeMaterial","fog":false,"lights":true,"vertex":"A9543A4D-4036-4AB3-AEF1-0AE10CFDD4A6","fragment":"A9543A4D-4036-4AB3-AEF1-0AE10CFDD4A6"}},"material":"BCB86F69-822F-4F9C-838B-70F657904D05"} \ No newline at end of file +{"nodes":{"A9543A4D-4036-4AB3-AEF1-0AE10CFDD4A6":{"uuid":"A9543A4D-4036-4AB3-AEF1-0AE10CFDD4A6","nodeType":"Phong","position":"A298C150-1E98-425D-8552-CF4690C3238E","color":"DCD2B815-345D-4600-BAFD-BE26925C60E6","specular":"DCD2B815-345D-4600-BAFD-BE26925C60E6","shininess":"5E1EEAA6-F057-4D5F-8607-E9F8265D2B0A","emissive":"BF320EA1-F523-4314-9B87-07E33F39CC6C"},"A298C150-1E98-425D-8552-CF4690C3238E":{"uuid":"A298C150-1E98-425D-8552-CF4690C3238E","nodeType":"Operator","a":"6449FE7E-56E7-490E-9CA9-9F5E9A540AFD","b":"09ECA9C2-8B78-422B-B3DA-2194BCBC5FCA","op":"+"},"6449FE7E-56E7-490E-9CA9-9F5E9A540AFD":{"uuid":"6449FE7E-56E7-490E-9CA9-9F5E9A540AFD","nodeType":"Position","scope":"local"},"09ECA9C2-8B78-422B-B3DA-2194BCBC5FCA":{"uuid":"09ECA9C2-8B78-422B-B3DA-2194BCBC5FCA","nodeType":"Operator","a":"C4573235-0C78-460A-BB35-E41470304BD5","b":"1FF6B149-BCA7-4F37-91E9-8AFA8770F084","op":"*"},"C4573235-0C78-460A-BB35-E41470304BD5":{"uuid":"C4573235-0C78-460A-BB35-E41470304BD5","nodeType":"Operator","a":"0E355E3B-23AB-4225-9477-312295B18436","b":"ABD03824-B7F8-46A4-9006-03FBA06618A9","op":"*"},"0E355E3B-23AB-4225-9477-312295B18436":{"uuid":"0E355E3B-23AB-4225-9477-312295B18436","nodeType":"Normal","scope":"local"},"ABD03824-B7F8-46A4-9006-03FBA06618A9":{"uuid":"ABD03824-B7F8-46A4-9006-03FBA06618A9","nodeType":"Switch","node":"43D31AB8-1DD6-46BE-8969-0668FAB513E2","components":"w"},"43D31AB8-1DD6-46BE-8969-0668FAB513E2":{"uuid":"43D31AB8-1DD6-46BE-8969-0668FAB513E2","nodeType":"Texture","value":"cloud","uv":"273D729E-E18D-47AE-8299-F069FDB6C43A","project":false},"273D729E-E18D-47AE-8299-F069FDB6C43A":{"uuid":"273D729E-E18D-47AE-8299-F069FDB6C43A","nodeType":"Operator","a":"C46D2A54-57A8-4649-AF9B-09D011AF3BFD","b":"C43B8DA9-AFF5-4690-B2EA-3EED061C0662","op":"+"},"C46D2A54-57A8-4649-AF9B-09D011AF3BFD":{"uuid":"C46D2A54-57A8-4649-AF9B-09D011AF3BFD","nodeType":"Operator","a":"F81EC887-A160-455B-B1DE-A0FA2B7FAC36","b":"801913CD-EC7A-47BE-A54C-3D86020B0847","op":"*"},"F81EC887-A160-455B-B1DE-A0FA2B7FAC36":{"uuid":"F81EC887-A160-455B-B1DE-A0FA2B7FAC36","nodeType":"Timer","name":"time","scope":"global","scale":1,"useTimeScale":false},"801913CD-EC7A-47BE-A54C-3D86020B0847":{"uuid":"801913CD-EC7A-47BE-A54C-3D86020B0847","nodeType":"Float","name":"speed","value":0.2},"C43B8DA9-AFF5-4690-B2EA-3EED061C0662":{"uuid":"C43B8DA9-AFF5-4690-B2EA-3EED061C0662","nodeType":"UV","index":0},"1FF6B149-BCA7-4F37-91E9-8AFA8770F084":{"uuid":"1FF6B149-BCA7-4F37-91E9-8AFA8770F084","nodeType":"Float","value":2},"DCD2B815-345D-4600-BAFD-BE26925C60E6":{"uuid":"DCD2B815-345D-4600-BAFD-BE26925C60E6","nodeType":"Color","r":0,"g":0,"b":0},"5E1EEAA6-F057-4D5F-8607-E9F8265D2B0A":{"uuid":"5E1EEAA6-F057-4D5F-8607-E9F8265D2B0A","nodeType":"Float","value":30},"BF320EA1-F523-4314-9B87-07E33F39CC6C":{"uuid":"BF320EA1-F523-4314-9B87-07E33F39CC6C","nodeType":"Math3","a":"F9EA5DC0-2BC8-4C38-A480-1DA3D0680AAE","b":"65010573-EE24-42A3-B32C-3945F3CF2E93","c":"ABD03824-B7F8-46A4-9006-03FBA06618A9","method":"mix"},"F9EA5DC0-2BC8-4C38-A480-1DA3D0680AAE":{"uuid":"F9EA5DC0-2BC8-4C38-A480-1DA3D0680AAE","nodeType":"Color","r":0,"g":0.32941176470588235,"b":0.8745098039215686},"65010573-EE24-42A3-B32C-3945F3CF2E93":{"uuid":"65010573-EE24-42A3-B32C-3945F3CF2E93","nodeType":"Color","r":1,"g":1,"b":1}},"materials":{"BCB86F69-822F-4F9C-838B-70F657904D05":{"uuid":"BCB86F69-822F-4F9C-838B-70F657904D05","type":"PhongNodeMaterial","fog":false,"lights":true,"vertex":"A9543A4D-4036-4AB3-AEF1-0AE10CFDD4A6","fragment":"A9543A4D-4036-4AB3-AEF1-0AE10CFDD4A6"}},"material":"BCB86F69-822F-4F9C-838B-70F657904D05"} \ No newline at end of file diff --git a/examples/nodes/wave.json b/examples/nodes/wave.json index e55358ec771fbd0b31b38c415aeca76317af7f75..737f5fe6e17b79dadd0e46c37a9d97d99e50fe49 100644 --- a/examples/nodes/wave.json +++ b/examples/nodes/wave.json @@ -1 +1 @@ -{"nodes":{"6BB91CE5-93BA-41BF-88C6-8D03721D4790":{"uuid":"6BB91CE5-93BA-41BF-88C6-8D03721D4790","nodeType":"Phong","transform":"39ED31F8-337B-49A4-9DBE-B43B1F5D180B","color":"1628C697-A4FC-4F02-9746-1CFAC6C6E85B","specular":"D730CA9D-A641-4289-BEF8-348CDD7218B6","shininess":"73E26FEC-C8C2-4E9E-8A4A-209A88156348"},"39ED31F8-337B-49A4-9DBE-B43B1F5D180B":{"uuid":"39ED31F8-337B-49A4-9DBE-B43B1F5D180B","nodeType":"Operator","a":"28F9F474-E77F-4373-BA46-D39F8588A56B","b":"B792813E-FC18-4440-8256-E4030E9D7E3A","op":"+"},"28F9F474-E77F-4373-BA46-D39F8588A56B":{"uuid":"28F9F474-E77F-4373-BA46-D39F8588A56B","nodeType":"Position","scope":"local"},"B792813E-FC18-4440-8256-E4030E9D7E3A":{"uuid":"B792813E-FC18-4440-8256-E4030E9D7E3A","nodeType":"Join","inputs":{"x":"F84376EF-6595-4A0F-AE1C-C183AE4D6392","y":"B7A4178E-D407-4444-9633-741A8C2DAD09","z":"F5785794-4DB6-47F6-AAB6-78DFC896B782"}},"F84376EF-6595-4A0F-AE1C-C183AE4D6392":{"uuid":"F84376EF-6595-4A0F-AE1C-C183AE4D6392","nodeType":"Float","value":0},"B7A4178E-D407-4444-9633-741A8C2DAD09":{"uuid":"B7A4178E-D407-4444-9633-741A8C2DAD09","nodeType":"Operator","a":"526B9B70-CBA1-47E4-9CEF-0CE5A9C4F041","b":"0A80D285-164D-4857-B8B9-30CE5CEC6931","op":"*"},"526B9B70-CBA1-47E4-9CEF-0CE5A9C4F041":{"uuid":"526B9B70-CBA1-47E4-9CEF-0CE5A9C4F041","nodeType":"Switch","node":"575F9E64-5B6D-4A95-9522-3A27919165BF","components":"x"},"575F9E64-5B6D-4A95-9522-3A27919165BF":{"uuid":"575F9E64-5B6D-4A95-9522-3A27919165BF","nodeType":"Math1","a":"4EF09677-828F-4164-BE18-2E8E87A3E969","method":"sin"},"4EF09677-828F-4164-BE18-2E8E87A3E969":{"uuid":"4EF09677-828F-4164-BE18-2E8E87A3E969","nodeType":"Operator","a":"DA817C54-9793-4850-9B90-A087050C6335","b":"CE06CC57-FAFF-4EF7-A0E3-1D71ED0A4EFD","op":"+"},"DA817C54-9793-4850-9B90-A087050C6335":{"uuid":"DA817C54-9793-4850-9B90-A087050C6335","nodeType":"Operator","a":"87304A41-2F18-4A98-92F1-9869F01786D3","b":"ECE889D2-A244-49EF-9ECF-BB685CD84828","op":"*"},"87304A41-2F18-4A98-92F1-9869F01786D3":{"uuid":"87304A41-2F18-4A98-92F1-9869F01786D3","nodeType":"Position","scope":"local"},"ECE889D2-A244-49EF-9ECF-BB685CD84828":{"uuid":"ECE889D2-A244-49EF-9ECF-BB685CD84828","nodeType":"Float","value":0.4},"CE06CC57-FAFF-4EF7-A0E3-1D71ED0A4EFD":{"uuid":"CE06CC57-FAFF-4EF7-A0E3-1D71ED0A4EFD","nodeType":"Operator","a":"D035D8DE-7C30-4372-A5E5-9A03169CFA96","b":"2090FF81-9723-4F1F-BF10-2F223F879DA5","op":"*"},"D035D8DE-7C30-4372-A5E5-9A03169CFA96":{"uuid":"D035D8DE-7C30-4372-A5E5-9A03169CFA96","nodeType":"Timer","name":"time","scope":"global","scale":1,"useTimeScale":false},"2090FF81-9723-4F1F-BF10-2F223F879DA5":{"uuid":"2090FF81-9723-4F1F-BF10-2F223F879DA5","nodeType":"Float","name":"speed","value":5},"0A80D285-164D-4857-B8B9-30CE5CEC6931":{"uuid":"0A80D285-164D-4857-B8B9-30CE5CEC6931","nodeType":"Float","value":1},"F5785794-4DB6-47F6-AAB6-78DFC896B782":{"uuid":"F5785794-4DB6-47F6-AAB6-78DFC896B782","nodeType":"Float","value":0},"1628C697-A4FC-4F02-9746-1CFAC6C6E85B":{"uuid":"1628C697-A4FC-4F02-9746-1CFAC6C6E85B","nodeType":"Math3","a":"48DEB7D7-83ED-4679-BB0B-45A11052AA5F","b":"8C0EACD5-DEA2-431B-B083-06FB93DB7D2A","c":"526B9B70-CBA1-47E4-9CEF-0CE5A9C4F041","method":"mix"},"48DEB7D7-83ED-4679-BB0B-45A11052AA5F":{"uuid":"48DEB7D7-83ED-4679-BB0B-45A11052AA5F","nodeType":"Color","r":0,"g":0.32941176470588235,"b":0.8745098039215686},"8C0EACD5-DEA2-431B-B083-06FB93DB7D2A":{"uuid":"8C0EACD5-DEA2-431B-B083-06FB93DB7D2A","nodeType":"Color","r":1,"g":1,"b":1},"D730CA9D-A641-4289-BEF8-348CDD7218B6":{"uuid":"D730CA9D-A641-4289-BEF8-348CDD7218B6","nodeType":"Color","r":0.06666666666666667,"g":0.06666666666666667,"b":0.06666666666666667},"73E26FEC-C8C2-4E9E-8A4A-209A88156348":{"uuid":"73E26FEC-C8C2-4E9E-8A4A-209A88156348","nodeType":"Float","value":30}},"materials":{"7DCC94F3-82FE-4A67-B5DB-8ACE85789BAA":{"uuid":"7DCC94F3-82FE-4A67-B5DB-8ACE85789BAA","type":"PhongNodeMaterial","fog":false,"lights":true,"vertex":"6BB91CE5-93BA-41BF-88C6-8D03721D4790","fragment":"6BB91CE5-93BA-41BF-88C6-8D03721D4790"}},"material":"7DCC94F3-82FE-4A67-B5DB-8ACE85789BAA"} \ No newline at end of file +{"nodes":{"6BB91CE5-93BA-41BF-88C6-8D03721D4790":{"uuid":"6BB91CE5-93BA-41BF-88C6-8D03721D4790","nodeType":"Phong","position":"39ED31F8-337B-49A4-9DBE-B43B1F5D180B","color":"1628C697-A4FC-4F02-9746-1CFAC6C6E85B","specular":"D730CA9D-A641-4289-BEF8-348CDD7218B6","shininess":"73E26FEC-C8C2-4E9E-8A4A-209A88156348"},"39ED31F8-337B-49A4-9DBE-B43B1F5D180B":{"uuid":"39ED31F8-337B-49A4-9DBE-B43B1F5D180B","nodeType":"Operator","a":"28F9F474-E77F-4373-BA46-D39F8588A56B","b":"B792813E-FC18-4440-8256-E4030E9D7E3A","op":"+"},"28F9F474-E77F-4373-BA46-D39F8588A56B":{"uuid":"28F9F474-E77F-4373-BA46-D39F8588A56B","nodeType":"Position","scope":"local"},"B792813E-FC18-4440-8256-E4030E9D7E3A":{"uuid":"B792813E-FC18-4440-8256-E4030E9D7E3A","nodeType":"Join","inputs":{"x":"F84376EF-6595-4A0F-AE1C-C183AE4D6392","y":"B7A4178E-D407-4444-9633-741A8C2DAD09","z":"F5785794-4DB6-47F6-AAB6-78DFC896B782"}},"F84376EF-6595-4A0F-AE1C-C183AE4D6392":{"uuid":"F84376EF-6595-4A0F-AE1C-C183AE4D6392","nodeType":"Float","value":0},"B7A4178E-D407-4444-9633-741A8C2DAD09":{"uuid":"B7A4178E-D407-4444-9633-741A8C2DAD09","nodeType":"Operator","a":"526B9B70-CBA1-47E4-9CEF-0CE5A9C4F041","b":"0A80D285-164D-4857-B8B9-30CE5CEC6931","op":"*"},"526B9B70-CBA1-47E4-9CEF-0CE5A9C4F041":{"uuid":"526B9B70-CBA1-47E4-9CEF-0CE5A9C4F041","nodeType":"Switch","node":"575F9E64-5B6D-4A95-9522-3A27919165BF","components":"x"},"575F9E64-5B6D-4A95-9522-3A27919165BF":{"uuid":"575F9E64-5B6D-4A95-9522-3A27919165BF","nodeType":"Math1","a":"4EF09677-828F-4164-BE18-2E8E87A3E969","method":"sin"},"4EF09677-828F-4164-BE18-2E8E87A3E969":{"uuid":"4EF09677-828F-4164-BE18-2E8E87A3E969","nodeType":"Operator","a":"DA817C54-9793-4850-9B90-A087050C6335","b":"CE06CC57-FAFF-4EF7-A0E3-1D71ED0A4EFD","op":"+"},"DA817C54-9793-4850-9B90-A087050C6335":{"uuid":"DA817C54-9793-4850-9B90-A087050C6335","nodeType":"Operator","a":"87304A41-2F18-4A98-92F1-9869F01786D3","b":"ECE889D2-A244-49EF-9ECF-BB685CD84828","op":"*"},"87304A41-2F18-4A98-92F1-9869F01786D3":{"uuid":"87304A41-2F18-4A98-92F1-9869F01786D3","nodeType":"Position","scope":"local"},"ECE889D2-A244-49EF-9ECF-BB685CD84828":{"uuid":"ECE889D2-A244-49EF-9ECF-BB685CD84828","nodeType":"Float","value":0.4},"CE06CC57-FAFF-4EF7-A0E3-1D71ED0A4EFD":{"uuid":"CE06CC57-FAFF-4EF7-A0E3-1D71ED0A4EFD","nodeType":"Operator","a":"D035D8DE-7C30-4372-A5E5-9A03169CFA96","b":"2090FF81-9723-4F1F-BF10-2F223F879DA5","op":"*"},"D035D8DE-7C30-4372-A5E5-9A03169CFA96":{"uuid":"D035D8DE-7C30-4372-A5E5-9A03169CFA96","nodeType":"Timer","name":"time","scope":"global","scale":1,"useTimeScale":false},"2090FF81-9723-4F1F-BF10-2F223F879DA5":{"uuid":"2090FF81-9723-4F1F-BF10-2F223F879DA5","nodeType":"Float","name":"speed","value":5},"0A80D285-164D-4857-B8B9-30CE5CEC6931":{"uuid":"0A80D285-164D-4857-B8B9-30CE5CEC6931","nodeType":"Float","value":1},"F5785794-4DB6-47F6-AAB6-78DFC896B782":{"uuid":"F5785794-4DB6-47F6-AAB6-78DFC896B782","nodeType":"Float","value":0},"1628C697-A4FC-4F02-9746-1CFAC6C6E85B":{"uuid":"1628C697-A4FC-4F02-9746-1CFAC6C6E85B","nodeType":"Math3","a":"48DEB7D7-83ED-4679-BB0B-45A11052AA5F","b":"8C0EACD5-DEA2-431B-B083-06FB93DB7D2A","c":"526B9B70-CBA1-47E4-9CEF-0CE5A9C4F041","method":"mix"},"48DEB7D7-83ED-4679-BB0B-45A11052AA5F":{"uuid":"48DEB7D7-83ED-4679-BB0B-45A11052AA5F","nodeType":"Color","r":0,"g":0.32941176470588235,"b":0.8745098039215686},"8C0EACD5-DEA2-431B-B083-06FB93DB7D2A":{"uuid":"8C0EACD5-DEA2-431B-B083-06FB93DB7D2A","nodeType":"Color","r":1,"g":1,"b":1},"D730CA9D-A641-4289-BEF8-348CDD7218B6":{"uuid":"D730CA9D-A641-4289-BEF8-348CDD7218B6","nodeType":"Color","r":0.06666666666666667,"g":0.06666666666666667,"b":0.06666666666666667},"73E26FEC-C8C2-4E9E-8A4A-209A88156348":{"uuid":"73E26FEC-C8C2-4E9E-8A4A-209A88156348","nodeType":"Float","value":30}},"materials":{"7DCC94F3-82FE-4A67-B5DB-8ACE85789BAA":{"uuid":"7DCC94F3-82FE-4A67-B5DB-8ACE85789BAA","type":"PhongNodeMaterial","fog":false,"lights":true,"vertex":"6BB91CE5-93BA-41BF-88C6-8D03721D4790","fragment":"6BB91CE5-93BA-41BF-88C6-8D03721D4790"}},"material":"7DCC94F3-82FE-4A67-B5DB-8ACE85789BAA"} \ No newline at end of file diff --git a/examples/webgl_loader_nodes.html b/examples/webgl_loader_nodes.html index c192f21067c1da7f38ae6a5f43405500e2052796..ea748474efa1904a276b562adfc14761bcc5e627 100644 --- a/examples/webgl_loader_nodes.html +++ b/examples/webgl_loader_nodes.html @@ -42,187 +42,187 @@ diff --git a/examples/webgl_materials_compile.html b/examples/webgl_materials_compile.html index b3668303dd0f9538e14b589b155543db5c8fa562..f155129843db334ad2854d6f99c62102ea690991 100644 --- a/examples/webgl_materials_compile.html +++ b/examples/webgl_materials_compile.html @@ -207,10 +207,10 @@ mtl.emissive = cos; - var transformer = new THREE.FunctionNode( "position + 0.0 * " + Math.random(), "vec3", [ ]); + var transformer = new THREE.ExpressionNode( "position + 0.0 * " + Math.random(), "vec3", [ ]); mtl.transform = transformer; - // build shader + // build shader ( ignore auto build ) mtl.build(); // set material diff --git a/examples/webgl_materials_nodes.html b/examples/webgl_materials_nodes.html index 70f193a194fbe52c18bc94590eb7bcf463b49c24..85dc81a9906cbc65402419e4d0587d5f9176e6b6 100644 --- a/examples/webgl_materials_nodes.html +++ b/examples/webgl_materials_nodes.html @@ -42,2435 +42,2672 @@ diff --git a/examples/webgl_mirror_nodes.html b/examples/webgl_mirror_nodes.html index d750a5e5a7b12b5dff8351bf2c0c6b0096f8cbc8..77a914a09ec05e71f1aaa6b0d04cb22315ad9aef 100644 --- a/examples/webgl_mirror_nodes.html +++ b/examples/webgl_mirror_nodes.html @@ -42,243 +42,242 @@ diff --git a/examples/webgl_performance_nodes.html b/examples/webgl_performance_nodes.html new file mode 100644 index 0000000000000000000000000000000000000000..8fc1f42de15896b6263951db40e608fe55c85168 --- /dev/null +++ b/examples/webgl_performance_nodes.html @@ -0,0 +1,269 @@ + + + + three.js webgl - performance [nodes] + + + + + + + + + +
+ three.js - NodeMaterial Performance
+
+ Node Material System +
+
+ StandardNodeMaterial | + None +
+
+ MeshStandardNodeMaterial | + None +
+
+ Current Material System +
+
+ MeshStandardMaterial | + None +
+
+ Click to benchmark +
+ + + + + diff --git a/examples/webgl_postprocessing_nodes.html b/examples/webgl_postprocessing_nodes.html index 7cba21bbe6b4f87b39b5c30054a76bf65276f8fc..94e1a9c2bdc905af969f7f8892af73910e58e232 100644 --- a/examples/webgl_postprocessing_nodes.html +++ b/examples/webgl_postprocessing_nodes.html @@ -34,27 +34,19 @@ - - - - - - - diff --git a/examples/webgl_postprocessing_nodes_pass.html b/examples/webgl_postprocessing_nodes_pass.html new file mode 100644 index 0000000000000000000000000000000000000000..818383295324c5a3922363c6637c951283998088 --- /dev/null +++ b/examples/webgl_postprocessing_nodes_pass.html @@ -0,0 +1,560 @@ + + + + three.js webgl - postprocessing with nodes + + + + + +
+ three.js - Node-Based Post-Processing +
+ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/webgl_sprites_nodes.html b/examples/webgl_sprites_nodes.html index 80ef0624ce4e61866496bdd1a2fe6b5936159ebf..7aa62e27eddd6d30293e14b4236dcfe39fe915ec 100644 --- a/examples/webgl_sprites_nodes.html +++ b/examples/webgl_sprites_nodes.html @@ -41,218 +41,215 @@