NodeMaterialLoader.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. /**
  2. * @author sunag / http://www.sunag.com.br/
  3. */
  4. THREE.NodeMaterialLoader = function ( manager, library ) {
  5. this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
  6. this.nodes = {};
  7. this.materials = {};
  8. this.passes = {};
  9. this.names = {};
  10. this.library = library || {};
  11. };
  12. THREE.NodeMaterialLoaderUtils = {
  13. replaceUUIDObject: function ( object, uuid, value, recursive ) {
  14. recursive = recursive !== undefined ? recursive : true;
  15. if ( typeof uuid === "object" ) uuid = uuid.uuid;
  16. if ( typeof object === "object" ) {
  17. var keys = Object.keys( object );
  18. for ( var i = 0; i < keys.length; i ++ ) {
  19. var key = keys[ i ];
  20. if ( recursive ) {
  21. object[ key ] = this.replaceUUIDObject( object[ key ], uuid, value );
  22. }
  23. if ( key === uuid ) {
  24. object[ uuid ] = object[ key ];
  25. delete object[ key ];
  26. }
  27. }
  28. }
  29. return object === uuid ? value : object;
  30. },
  31. replaceUUID: function ( json, uuid, value ) {
  32. this.replaceUUIDObject( json, uuid, value, false );
  33. this.replaceUUIDObject( json.nodes, uuid, value );
  34. this.replaceUUIDObject( json.materials, uuid, value );
  35. this.replaceUUIDObject( json.passes, uuid, value );
  36. this.replaceUUIDObject( json.library, uuid, value, false );
  37. return json;
  38. }
  39. };
  40. Object.assign( THREE.NodeMaterialLoader.prototype, {
  41. load: function ( url, onLoad, onProgress, onError ) {
  42. var scope = this;
  43. var loader = new THREE.FileLoader( scope.manager );
  44. loader.load( url, function ( text ) {
  45. onLoad( scope.parse( JSON.parse( text ) ) );
  46. }, onProgress, onError );
  47. return this;
  48. },
  49. getObjectByName: function ( uuid ) {
  50. return this.names[ uuid ];
  51. },
  52. getObjectById: function ( uuid ) {
  53. return this.library[ uuid ] || this.nodes[ uuid ] || this.names[ uuid ];
  54. },
  55. getNode: function ( uuid ) {
  56. var object = this.getObjectById( uuid );
  57. if ( ! object ) {
  58. console.warn( "Node \"" + uuid + "\" not found." );
  59. }
  60. return object;
  61. },
  62. parse: function ( json ) {
  63. var uuid, node, object, prop, i;
  64. for ( uuid in json.nodes ) {
  65. node = json.nodes[ uuid ];
  66. object = new THREE[ node.type ]();
  67. if ( node.name ) {
  68. object.name = node.name;
  69. this.names[ object.name ] = object;
  70. } else {
  71. // ignore "uniform" shader input ( for optimization )
  72. object.readonly = true;
  73. }
  74. if ( node.readonly !== undefined ) object.readonly = node.readonly;
  75. this.nodes[ uuid ] = object;
  76. }
  77. for ( uuid in json.materials ) {
  78. node = json.materials[ uuid ];
  79. object = new THREE[ node.type ]();
  80. if ( node.name ) {
  81. object.name = node.name;
  82. this.names[ object.name ] = object;
  83. }
  84. this.materials[ uuid ] = object;
  85. }
  86. for ( uuid in json.passes ) {
  87. node = json.passes[ uuid ];
  88. object = new THREE[ node.type ]();
  89. if ( node.name ) {
  90. object.name = node.name;
  91. this.names[ object.name ] = object;
  92. }
  93. this.passes[ uuid ] = object;
  94. }
  95. if ( json.material ) this.material = this.materials[ uuid ];
  96. if ( json.pass ) this.pass = this.passes[ uuid ];
  97. for ( uuid in json.nodes ) {
  98. node = json.nodes[ uuid ];
  99. object = this.nodes[ uuid ];
  100. switch ( node.type ) {
  101. case "IntNode":
  102. case "FloatNode":
  103. object.value = node.value;
  104. break;
  105. case "ColorNode":
  106. object.value.copy( node );
  107. break;
  108. case "Vector2Node":
  109. object.x = node.x;
  110. object.y = node.y;
  111. break;
  112. case "Vector3Node":
  113. object.x = node.x;
  114. object.y = node.y;
  115. object.z = node.z;
  116. break;
  117. case "Vector4Node":
  118. object.x = node.x;
  119. object.y = node.y;
  120. object.z = node.z;
  121. object.w = node.w;
  122. break;
  123. case "Matrix3Node":
  124. case "Matrix4Node":
  125. object.value.fromArray( node.elements );
  126. break;
  127. case "OperatorNode":
  128. object.a = this.getNode( node.a );
  129. object.b = this.getNode( node.b );
  130. object.op = node.op;
  131. break;
  132. case "Math1Node":
  133. object.a = this.getNode( node.a );
  134. object.method = node.method;
  135. break;
  136. case "Math2Node":
  137. object.a = this.getNode( node.a );
  138. object.b = this.getNode( node.b );
  139. object.method = node.method;
  140. break;
  141. case "Math3Node":
  142. object.a = this.getNode( node.a );
  143. object.b = this.getNode( node.b );
  144. object.c = this.getNode( node.c );
  145. object.method = node.method;
  146. break;
  147. case "UVNode":
  148. case "ColorsNode":
  149. object.index = node.index;
  150. break;
  151. case "LuminanceNode":
  152. object.rgb = this.getNode( node.rgb );
  153. break;
  154. case "PositionNode":
  155. case "NormalNode":
  156. case "ReflectNode":
  157. case "LightNode":
  158. object.scope = node.scope;
  159. break;
  160. case "SwitchNode":
  161. object.node = this.getNode( node.node );
  162. object.components = node.components;
  163. break;
  164. case "JoinNode":
  165. for ( prop in node.inputs ) {
  166. object[ prop ] = this.getNode( node.inputs[ prop ] );
  167. }
  168. break;
  169. case "CameraNode":
  170. object.setScope( node.scope );
  171. if ( node.camera ) object.setCamera( this.getNode( node.camera ) );
  172. switch ( node.scope ) {
  173. case THREE.CameraNode.DEPTH:
  174. object.near.number = node.near;
  175. object.far.number = node.far;
  176. break;
  177. }
  178. break;
  179. case "ColorAdjustmentNode":
  180. object.rgb = this.getNode( node.rgb );
  181. object.adjustment = this.getNode( node.adjustment );
  182. object.method = node.method;
  183. break;
  184. case "UVTransformNode":
  185. object.uv = this.getNode( node.uv );
  186. object.transform = this.getNode( node.transform );
  187. break;
  188. case "BumpNode":
  189. object.value = this.getNode( node.value );
  190. object.coord = this.getNode( node.coord );
  191. object.scale = this.getNode( node.scale );
  192. break;
  193. case "BlurNode":
  194. object.value = this.getNode( node.value );
  195. object.coord = this.getNode( node.coord );
  196. object.scale = this.getNode( node.scale );
  197. object.value = this.getNode( node.value );
  198. object.coord = this.getNode( node.coord );
  199. object.radius = this.getNode( node.radius );
  200. if ( node.size !== undefined ) object.size = new THREE.Vector2( node.size.x, node.size.y );
  201. object.blurX = node.blurX;
  202. object.blurY = node.blurY;
  203. break;
  204. case "ResolutionNode":
  205. object.renderer = this.getNode( node.renderer );
  206. break;
  207. case "ScreenUVNode":
  208. object.resolution = this.getNode( node.resolution );
  209. break;
  210. case "VelocityNode":
  211. if ( node.target ) object.setTarget( this.getNode( node.target ) );
  212. object.setParams( node.params );
  213. break;
  214. case "TimerNode":
  215. object.scope = node.scope;
  216. object.scale = node.scale;
  217. break;
  218. case "ConstNode":
  219. object.name = node.name;
  220. object.type = node.out;
  221. object.value = node.value;
  222. object.useDefine = node.useDefine === true;
  223. break;
  224. case "AttributeNode":
  225. case "VarNode":
  226. object.type = node.out;
  227. break;
  228. case "ReflectorNode":
  229. object.setMirror( this.getNode( node.mirror ) );
  230. if ( node.offset ) object.offset = this.getNode( node.offset );
  231. break;
  232. case "NoiseNode":
  233. object.coord = this.getNode( node.coord );
  234. break;
  235. case "FunctionNode":
  236. object.isMethod = node.isMethod;
  237. object.useKeywords = node.useKeywords;
  238. object.extensions = node.extensions;
  239. object.keywords = {};
  240. for ( prop in node.keywords ) {
  241. object.keywords[ prop ] = this.getNode( node.keywords[ prop ] );
  242. }
  243. if ( node.includes ) {
  244. for ( i = 0; i < node.includes.length; i ++ ) {
  245. object.includes.push( this.getNode( node.includes[ i ] ) );
  246. }
  247. }
  248. object.eval( node.src, object.includes, object.extensions, object.keywords );
  249. if ( ! object.isMethod ) object.type = node.out;
  250. break;
  251. case "FunctionCallNode":
  252. for ( prop in node.inputs ) {
  253. object.inputs[ prop ] = this.getNode( node.inputs[ prop ] );
  254. }
  255. object.value = this.getNode( node.value );
  256. break;
  257. case "TextureNode":
  258. case "CubeTextureNode":
  259. case "ScreenNode":
  260. if ( node.value ) object.value = this.getNode( node.value );
  261. object.coord = this.getNode( node.coord );
  262. if ( node.bias ) object.bias = this.getNode( node.bias );
  263. if ( object.project !== undefined ) object.project = node.project;
  264. break;
  265. case "RoughnessToBlinnExponentNode":
  266. break;
  267. case "RawNode":
  268. object.value = this.getNode( node.value );
  269. break;
  270. case "StandardNode":
  271. case "PhongNode":
  272. case "SpriteNode":
  273. object.color = this.getNode( node.color );
  274. if ( node.alpha ) object.alpha = this.getNode( node.alpha );
  275. if ( node.specular ) object.specular = this.getNode( node.specular );
  276. if ( node.shininess ) object.shininess = this.getNode( node.shininess );
  277. if ( node.roughness ) object.roughness = this.getNode( node.roughness );
  278. if ( node.metalness ) object.metalness = this.getNode( node.metalness );
  279. if ( node.reflectivity ) object.reflectivity = this.getNode( node.reflectivity );
  280. if ( node.clearCoat ) object.clearCoat = this.getNode( node.clearCoat );
  281. if ( node.clearCoatRoughness ) object.clearCoatRoughness = this.getNode( node.clearCoatRoughness );
  282. if ( node.normal ) object.normal = this.getNode( node.normal );
  283. if ( node.normalScale ) object.normalScale = this.getNode( node.normalScale );
  284. if ( node.emissive ) object.emissive = this.getNode( node.emissive );
  285. if ( node.ambient ) object.ambient = this.getNode( node.ambient );
  286. if ( node.shadow ) object.shadow = this.getNode( node.shadow );
  287. if ( node.light ) object.light = this.getNode( node.light );
  288. if ( node.ao ) object.ao = this.getNode( node.ao );
  289. if ( node.environment ) object.environment = this.getNode( node.environment );
  290. if ( node.environmentAlpha ) object.environmentAlpha = this.getNode( node.environmentAlpha );
  291. if ( node.transform ) object.transform = this.getNode( node.transform );
  292. if ( node.spherical === false ) object.spherical = false;
  293. break;
  294. default:
  295. console.warn( node.type, "not supported." );
  296. }
  297. }
  298. for ( uuid in json.materials ) {
  299. node = json.materials[ uuid ];
  300. object = this.materials[ uuid ];
  301. if ( node.name !== undefined ) object.name = node.name;
  302. if ( node.blending !== undefined ) object.blending = node.blending;
  303. if ( node.flatShading !== undefined ) object.flatShading = node.flatShading;
  304. if ( node.side !== undefined ) object.side = node.side;
  305. object.depthFunc = node.depthFunc;
  306. object.depthTest = node.depthTest;
  307. object.depthWrite = node.depthWrite;
  308. if ( node.wireframe !== undefined ) object.wireframe = node.wireframe;
  309. if ( node.wireframeLinewidth !== undefined ) object.wireframeLinewidth = node.wireframeLinewidth;
  310. if ( node.wireframeLinecap !== undefined ) object.wireframeLinecap = node.wireframeLinecap;
  311. if ( node.wireframeLinejoin !== undefined ) object.wireframeLinejoin = node.wireframeLinejoin;
  312. if ( node.skinning !== undefined ) object.skinning = node.skinning;
  313. if ( node.morphTargets !== undefined ) object.morphTargets = node.morphTargets;
  314. if ( node.visible !== undefined ) object.visible = node.visible;
  315. if ( node.userData !== undefined ) object.userData = node.userData;
  316. object.vertex = this.getNode( node.vertex );
  317. object.fragment = this.getNode( node.fragment );
  318. if ( object.vertex === object.fragment ) {
  319. // replace main node
  320. object.node = object.vertex;
  321. }
  322. if ( node.fog !== undefined ) object.fog = node.fog;
  323. if ( node.lights !== undefined ) object.lights = node.lights;
  324. if ( node.transparent !== undefined ) object.transparent = node.transparent;
  325. }
  326. for ( uuid in json.passes ) {
  327. node = json.passes[ uuid ];
  328. object = this.passes[ uuid ];
  329. object.value = this.getNode( node.value );
  330. }
  331. return this.material || this.pass || this;
  332. }
  333. } );