webgl_materials_nodes.html 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <title>WebGL NodeMaterial</title>
  5. <meta charset="utf-8">
  6. <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  7. <style>
  8. body {
  9. color: #fff;
  10. font-family:Monospace;
  11. font-size:13px;
  12. margin: 0px;
  13. text-align:center;
  14. overflow: hidden;
  15. }
  16. #info {
  17. color: #fff;
  18. position: absolute;
  19. top: 10px;
  20. width: 100%;
  21. text-align: center;
  22. display:block;
  23. }
  24. a { color: white }
  25. </style>
  26. </head>
  27. <body>
  28. <div id="container"></div>
  29. <div id="info">
  30. <a href="http://threejs.org" target="_blank">three.js</a> - Node-Based Material
  31. </div>
  32. <script src="../build/three.min.js"></script>
  33. <script src='js/geometries/TeapotBufferGeometry.js'></script>
  34. <script src="js/controls/OrbitControls.js"></script>
  35. <script src="js/libs/dat.gui.min.js"></script>
  36. <!-- NodeMaterial Base -->
  37. <script src="js/materials/nodes/NodeGL.js"></script>
  38. <script src="js/materials/nodes/NodeBuilder.js"></script>
  39. <script src="js/materials/nodes/NodeRaw.js"></script>
  40. <script src="js/materials/nodes/NodeTemp.js"></script>
  41. <script src="js/materials/nodes/NodeInput.js"></script>
  42. <script src="js/materials/nodes/NodeMaterial.js"></script>
  43. <script src="js/materials/nodes/NodeConst.js"></script>
  44. <script src="js/materials/nodes/NodeFunction.js"></script>
  45. <script src="js/materials/nodes/NodeFunctionCall.js"></script>
  46. <script src="js/materials/nodes/NodeLib.js"></script>
  47. <!-- Accessors -->
  48. <script src="js/materials/nodes/accessors/NodeColors.js"></script>
  49. <script src="js/materials/nodes/accessors/NodeCamera.js"></script>
  50. <script src="js/materials/nodes/accessors/NodeNormal.js"></script>
  51. <script src="js/materials/nodes/accessors/NodePosition.js"></script>
  52. <script src="js/materials/nodes/accessors/NodeReflect.js"></script>
  53. <script src="js/materials/nodes/accessors/NodeUV.js"></script>
  54. <!-- Inputs -->
  55. <script src="js/materials/nodes/inputs/NodeColor.js"></script>
  56. <script src="js/materials/nodes/inputs/NodeFloat.js"></script>
  57. <script src="js/materials/nodes/inputs/NodeInt.js"></script>
  58. <script src="js/materials/nodes/inputs/NodeVector2.js"></script>
  59. <script src="js/materials/nodes/inputs/NodeVector3.js"></script>
  60. <script src="js/materials/nodes/inputs/NodeVector4.js"></script>
  61. <script src="js/materials/nodes/inputs/NodeTexture.js"></script>
  62. <script src="js/materials/nodes/inputs/NodeCubeTexture.js"></script>
  63. <!-- Math -->
  64. <script src="js/materials/nodes/math/NodeMath1.js"></script>
  65. <script src="js/materials/nodes/math/NodeMath2.js"></script>
  66. <script src="js/materials/nodes/math/NodeMath3.js"></script>
  67. <script src="js/materials/nodes/math/NodeOperator.js"></script>
  68. <!-- Utils -->
  69. <script src="js/materials/nodes/utils/NodeJoin.js"></script>
  70. <script src="js/materials/nodes/utils/NodeSwitch.js"></script>
  71. <script src="js/materials/nodes/utils/NodeTime.js"></script>
  72. <script src="js/materials/nodes/utils/NodeRoughnessToBlinnExponent.js"></script>
  73. <!-- Interfaces -->
  74. <script src="js/materials/nodes/interfaces/NodePhong.js"></script>
  75. <script src="js/materials/nodes/interfaces/NodePhongMaterial.js"></script>
  76. <script src="js/materials/nodes/interfaces/NodeStandard.js"></script>
  77. <script src="js/materials/nodes/interfaces/NodeStandardMaterial.js"></script>
  78. <!-- Extras -->
  79. <script src="js/materials/nodes/extras/NodeVelocity.js"></script>
  80. <script>
  81. var container = document.getElementById( 'container' );
  82. var renderer, scene, camera, clock = new THREE.Clock(), fov = 50;
  83. var teapot, mesh;
  84. var controls;
  85. var move = false;
  86. var gui, guiElements = [];
  87. var param = { example: 'standard' };
  88. var brick = new THREE.TextureLoader().load( 'textures/brick_diffuse.jpg' );
  89. var grass = new THREE.TextureLoader().load( 'textures/terrain/grasslight-big.jpg' );
  90. var grassNormal = new THREE.TextureLoader().load( 'textures/terrain/grasslight-big-nm.jpg' );
  91. var decalDiffuse = new THREE.TextureLoader().load( 'textures/decal/decal-diffuse.png' );
  92. decalDiffuse.wrapS = decalDiffuse.wrapT = THREE.RepeatWrapping;
  93. var decalNormal = new THREE.TextureLoader().load( 'textures/decal/decal-normal.jpg' );
  94. var cloud = new THREE.TextureLoader().load( 'textures/lava/cloud.png' );
  95. cloud.wrapS = cloud.wrapT = THREE.RepeatWrapping;
  96. var cubemap = function() {
  97. var path = "textures/cube/Park2/";
  98. var format = '.jpg';
  99. var urls = [
  100. path + 'posx' + format, path + 'negx' + format,
  101. path + 'posy' + format, path + 'negy' + format,
  102. path + 'posz' + format, path + 'negz' + format
  103. ];
  104. var textureCube = new THREE.CubeTextureLoader().load( urls );
  105. textureCube.format = THREE.RGBFormat;
  106. return textureCube;
  107. }()
  108. window.addEventListener( 'load', init );
  109. function init() {
  110. renderer = new THREE.WebGLRenderer( { antialias: true } );
  111. renderer.setPixelRatio( window.devicePixelRatio );
  112. renderer.setSize( window.innerWidth, window.innerHeight );
  113. container.appendChild( renderer.domElement );
  114. scene = new THREE.Scene();
  115. camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1000 );
  116. camera.position.x = 50;
  117. camera.position.z = -50;
  118. camera.position.y = 30;
  119. camera.target = new THREE.Vector3();
  120. controls = new THREE.OrbitControls( camera, renderer.domElement );
  121. controls.minDistance = 50;
  122. controls.maxDistance = 200;
  123. scene.add( new THREE.AmbientLight( 0x464646 ) );
  124. var light = new THREE.DirectionalLight( 0xffddcc, 1 );
  125. light.position.set( 1, 0.75, 0.5 );
  126. scene.add( light );
  127. var light = new THREE.DirectionalLight( 0xccccff, 1 );
  128. light.position.set( -1, 0.75, -0.5 );
  129. scene.add( light );
  130. teapot = new THREE.TeapotBufferGeometry( 15, 18 );
  131. mesh = new THREE.Mesh( teapot );
  132. scene.add( mesh );
  133. window.addEventListener( 'resize', onWindowResize, false );
  134. updateMaterial();
  135. onWindowResize();
  136. animate();
  137. }
  138. function clearGui() {
  139. if (gui) gui.destroy();
  140. gui = new dat.GUI();
  141. var example = gui.add( param, 'example', {
  142. 'basic / standard (PBR)': 'standard',
  143. 'basic / phong': 'phong',
  144. 'basic / layers': 'layers',
  145. 'basic / rim': 'rim',
  146. 'adv / fresnel': 'fresnel',
  147. 'adv / saturation': 'saturation',
  148. 'adv / top-bottom': 'top-bottom',
  149. 'adv / caustic': 'caustic',
  150. 'adv / displace': 'displace',
  151. 'adv / camera-depth': 'camera-depth',
  152. 'adv / soft-body': 'soft-body',
  153. 'adv / wave': 'wave',
  154. 'misc / smoke' : 'smoke',
  155. 'misc / firefly' : 'firefly'
  156. } ).onFinishChange(function() {
  157. updateMaterial();
  158. } );
  159. gui.open();
  160. }
  161. function addGui( name, value, callback, isColor, min, max ) {
  162. var node;
  163. param[name] = value;
  164. if (isColor) {
  165. node = gui.addColor( param, name ).onChange(function() {
  166. callback( param[name] );
  167. } );
  168. }
  169. else {
  170. node = gui.add( param, name, min, max ).onChange(function() {
  171. callback( param[name] );
  172. } );
  173. }
  174. return node;
  175. }
  176. function updateMaterial() {
  177. move = false;
  178. if (mesh.material) mesh.material.dispose();
  179. var name = param.example;
  180. var mtl;
  181. clearGui();
  182. switch( name ) {
  183. case 'phong':
  184. // MATERIAL
  185. mtl = new THREE.NodePhongMaterial();
  186. //mtl.color = // albedo color
  187. //mtl.alpha = // opacity (0 at 1)
  188. //mtl.specular = // specular color
  189. //mtl.shininess = // shininess (float)
  190. //mtl.normal = // normalmap
  191. //mtl.normalScale = // normalmap scale
  192. //mtl.emissive = // emissive color
  193. //mtl.ambient = // ambient color
  194. //mtl.shadow = // shadowmap
  195. //mtl.ao = // ambient occlusion
  196. //mtl.environment = // reflection map (CubeMap recommended)
  197. //mtl.reflectivity = // environment intensity
  198. //mtl.transform = // vertex transformation
  199. var mask = new THREE.NodeSwitch(new THREE.NodeTexture(decalDiffuse), 'w');
  200. mtl.color = new THREE.NodeTexture(grass);
  201. mtl.specular = new THREE.NodeFloat(.5);
  202. mtl.shininess = new THREE.NodeFloat(15);
  203. mtl.environment = new THREE.NodeCubeTexture(cubemap);
  204. mtl.reflectivity = mask;
  205. mtl.normal = new THREE.NodeTexture(grassNormal);
  206. mtl.normalScale = new THREE.NodeMath1( mask, THREE.NodeMath1.INVERT );
  207. break;
  208. case 'standard':
  209. // MATERIAL
  210. mtl = new THREE.NodeStandardMaterial();
  211. //mtl.color = // albedo color
  212. //mtl.alpha = // opacity (0 at 1)
  213. //mtl.roughness = // roughness (float)
  214. //mtl.metalness = // metalness (float)
  215. //mtl.normal = // normalmap
  216. //mtl.normalScale = // normalmap scale
  217. //mtl.emissive = // emissive color
  218. //mtl.ambient = // ambient color
  219. //mtl.shadow = // shadowmap
  220. //mtl.ao = // ambient occlusion
  221. //mtl.environment = // reflection map (CubeMap recommended)
  222. //mtl.reflectivity = // environment intensity
  223. //mtl.transform = // vertex transformation
  224. var mask = new THREE.NodeSwitch(new THREE.NodeTexture(decalDiffuse), 'w');
  225. var normalScale = new THREE.NodeFloat(.3);
  226. var roughnessA = new THREE.NodeFloat(.5);
  227. var metalnessA = new THREE.NodeFloat(.5);
  228. var roughnessB = new THREE.NodeFloat(0);
  229. var metalnessB = new THREE.NodeFloat(1);
  230. var roughness = new THREE.NodeMath3(
  231. roughnessA,
  232. roughnessB,
  233. mask,
  234. THREE.NodeMath3.MIX
  235. );
  236. var metalness = new THREE.NodeMath3(
  237. metalnessA,
  238. metalnessB,
  239. mask,
  240. THREE.NodeMath3.MIX
  241. );
  242. var normalMask = new THREE.NodeOperator(
  243. new THREE.NodeMath1( mask, THREE.NodeMath1.INVERT ),
  244. normalScale,
  245. THREE.NodeOperator.MUL
  246. );
  247. mtl.color = new THREE.NodeColor(0xFFFFFF);
  248. mtl.roughness = roughness;
  249. mtl.metalness = metalness;
  250. mtl.environment = new THREE.NodeCubeTexture(cubemap);
  251. mtl.normal = new THREE.NodeTexture(grassNormal);
  252. mtl.normalScale = normalMask;
  253. // GUI
  254. addGui( 'color', mtl.color.value.getHex(), function( val ) {
  255. mtl.color.value.setHex( val );
  256. }, true );
  257. addGui( 'roughnessA', roughnessA.number, function( val ) {
  258. roughnessA.number = val;
  259. }, false, 0, 1 );
  260. addGui( 'metalnessA', metalnessA.number, function( val ) {
  261. metalnessA.number = val;
  262. }, false, 0, 1 );
  263. addGui( 'roughnessB', roughnessB.number, function( val ) {
  264. roughnessB.number = val;
  265. }, false, 0, 1 );
  266. addGui( 'metalnessB', metalnessB.number, function( val ) {
  267. metalnessB.number = val;
  268. }, false, 0, 1 );
  269. addGui( 'normalScale', normalScale.number, function( val ) {
  270. normalScale.number = val;
  271. }, false, 0, 1 );
  272. break;
  273. case 'wave':
  274. // MATERIAL
  275. mtl = new THREE.NodePhongMaterial();
  276. var time = new THREE.NodeTime();
  277. var speed = new THREE.NodeFloat(5);
  278. var scale = new THREE.NodeFloat(1);
  279. var worldScale = new THREE.NodeFloat(.4);
  280. var colorA = new THREE.NodeColor(0xFFFFFF);
  281. var colorB = new THREE.NodeColor(0x0054df);
  282. var uv = new THREE.NodeUV();
  283. var timeScale = new THREE.NodeOperator(
  284. time,
  285. speed,
  286. THREE.NodeOperator.MUL
  287. );
  288. var worldScl = new THREE.NodeOperator(
  289. new THREE.NodePosition(),
  290. worldScale,
  291. THREE.NodeOperator.MUL
  292. );
  293. var posContinuous = new THREE.NodeOperator(
  294. worldScl,
  295. timeScale,
  296. THREE.NodeOperator.ADD
  297. );
  298. var wave = new THREE.NodeMath1(posContinuous, THREE.NodeMath1.SIN);
  299. wave = new THREE.NodeSwitch(wave, 'x');
  300. var waveScale = new THREE.NodeOperator(
  301. wave,
  302. scale,
  303. THREE.NodeOperator.MUL
  304. );
  305. var displaceY = new THREE.NodeJoin(
  306. new THREE.NodeFloat(),
  307. waveScale,
  308. new THREE.NodeFloat()
  309. );
  310. var displace = new THREE.NodeOperator(
  311. new THREE.NodeNormal(),
  312. displaceY,
  313. THREE.NodeOperator.MUL
  314. );
  315. var blend = new THREE.NodeOperator(
  316. new THREE.NodePosition(),
  317. displaceY,
  318. THREE.NodeOperator.ADD
  319. );
  320. var color = new THREE.NodeMath3(
  321. colorB,
  322. colorA,
  323. wave,
  324. THREE.NodeMath3.MIX
  325. );
  326. mtl.color = color;
  327. mtl.transform = blend;
  328. // GUI
  329. addGui( 'speed', speed.number, function( val ) {
  330. speed.number = val;
  331. }, false, 0, 10 );
  332. addGui( 'scale', scale.number, function( val ) {
  333. scale.number = val;
  334. }, false, 0, 3 );
  335. addGui( 'worldScale', worldScale.number, function( val ) {
  336. worldScale.number = val;
  337. }, false, 0, 1 );
  338. addGui( 'colorA', colorA.value.getHex(), function( val ) {
  339. colorA.value.setHex( val );
  340. }, true );
  341. addGui( 'colorB', colorB.value.getHex(), function( val ) {
  342. colorB.value.setHex( val );
  343. }, true );
  344. addGui( 'useNormals', false, function( val ) {
  345. blend.b = val ? displace : displaceY;
  346. mtl.build();
  347. } );
  348. break;
  349. case 'rim':
  350. // MATERIAL
  351. mtl = new THREE.NodePhongMaterial();
  352. var intensity = 1.3;
  353. var power = new THREE.NodeFloat(3);
  354. var color = new THREE.NodeColor(0xFFFFFF);
  355. var viewZ = new THREE.NodeMath2(
  356. new THREE.NodeNormal( THREE.NodeNormal.VIEW ),
  357. new THREE.NodeVector3(0, 0, -intensity),
  358. THREE.NodeMath2.DOT
  359. );
  360. var rim = new THREE.NodeOperator(
  361. viewZ,
  362. new THREE.NodeFloat(intensity),
  363. THREE.NodeOperator.ADD
  364. );
  365. var rimPower = new THREE.NodeMath2(
  366. rim,
  367. power,
  368. THREE.NodeMath2.POW
  369. );
  370. var rimColor = new THREE.NodeOperator(
  371. rimPower,
  372. color,
  373. THREE.NodeOperator.MUL
  374. );
  375. mtl.color = new THREE.NodeColor(0x111111);
  376. mtl.emissive = rimColor;
  377. // GUI
  378. addGui( 'color', color.value.getHex(), function( val ) {
  379. color.value.setHex( val );
  380. }, true );
  381. addGui( 'intensity', intensity, function( val ) {
  382. intensity = val;
  383. viewZ.b.z = -intensity;
  384. rim.b.number = intensity;
  385. }, false, 0, 3 );
  386. addGui( 'power', power.number, function( val ) {
  387. power.number = val;
  388. }, false, 0, 6 );
  389. addGui( 'xray', false, function( val ) {
  390. if (val) {
  391. mtl.emissive = color;
  392. mtl.alpha = rimPower;
  393. mtl.blending = THREE.AdditiveBlending;
  394. mtl.depthWrite = false;
  395. }
  396. else {
  397. mtl.emissive = rimColor;
  398. mtl.alpha = null;
  399. mtl.blending = THREE.NormalBlending;
  400. mtl.depthWrite = true;
  401. }
  402. mtl.build();
  403. } );
  404. break;
  405. case 'fresnel':
  406. // MATERIAL
  407. mtl = new THREE.NodePhongMaterial();
  408. var reflectance = new THREE.NodeFloat(1.3);
  409. var power = new THREE.NodeFloat(1);
  410. var color = new THREE.NodeCubeTexture(cubemap);
  411. var viewZ = new THREE.NodeMath2(
  412. new THREE.NodeNormal( THREE.NodeNormal.VIEW ),
  413. new THREE.NodeVector3(0, 0, -1),
  414. THREE.NodeMath2.DOT
  415. );
  416. var theta = new THREE.NodeOperator(
  417. viewZ,
  418. new THREE.NodeFloat(1),
  419. THREE.NodeOperator.ADD
  420. );
  421. var thetaPower = new THREE.NodeMath2(
  422. theta,
  423. power,
  424. THREE.NodeMath2.POW
  425. );
  426. var fresnel = new THREE.NodeOperator(
  427. reflectance,
  428. thetaPower,
  429. THREE.NodeOperator.MUL
  430. );
  431. mtl.color = new THREE.NodeColor(0x3399FF);
  432. mtl.environment = color;
  433. mtl.reflectivity = new THREE.NodeMath1( fresnel, THREE.NodeMath1.SAT );
  434. // GUI
  435. addGui( 'reflectance', reflectance.number, function( val ) {
  436. reflectance.number = val;
  437. }, false, 0, 3 );
  438. addGui( 'power', power.number, function( val ) {
  439. power.number = val;
  440. }, false, 0, 5 );
  441. break;
  442. case 'layers':
  443. // MATERIAL
  444. mtl = new THREE.NodePhongMaterial();
  445. var tex1 = new THREE.NodeTexture(grass);
  446. var tex2 = new THREE.NodeTexture(brick);
  447. var offset = new THREE.NodeFloat(0);
  448. var scale = new THREE.NodeFloat(1);
  449. var uv = new THREE.NodeUV();
  450. var uvOffset = new THREE.NodeOperator(
  451. offset,
  452. uv,
  453. THREE.NodeOperator.ADD
  454. );
  455. var uvScale = new THREE.NodeOperator(
  456. uvOffset,
  457. scale,
  458. THREE.NodeOperator.MUL
  459. );
  460. var mask = new THREE.NodeTexture(decalDiffuse, uvScale);
  461. var maskAlphaChannel = new THREE.NodeSwitch(mask, 'w');
  462. var blend = new THREE.NodeMath3(
  463. tex1,
  464. tex2,
  465. maskAlphaChannel,
  466. THREE.NodeMath3.MIX
  467. );
  468. mtl.color = blend;
  469. // GUI
  470. addGui( 'offset', offset.number, function( val ) {
  471. offset.number = val;
  472. }, false, 0, 1 );
  473. addGui( 'scale', scale.number, function( val ) {
  474. scale.number = val;
  475. }, false, 0, 10 );
  476. break;
  477. case 'saturation':
  478. // MATERIAL
  479. mtl = new THREE.NodeStandardMaterial();
  480. var tex = new THREE.NodeTexture(brick);
  481. var sat = new THREE.NodeFloat(0);
  482. var satrgb = new THREE.NodeFunction([
  483. "vec3 satrgb(vec3 rgb, float adjustment) {",
  484. //"const vec3 W = vec3(0.2125, 0.7154, 0.0721);", // LUMA
  485. "vec3 intensity = vec3(dot(rgb, LUMA));",
  486. "return mix(intensity, rgb, adjustment);",
  487. "}"
  488. ].join( "\n" ));
  489. var saturation = new THREE.NodeFunctionCall(satrgb);
  490. saturation.input.rgb = tex;
  491. saturation.input.adjustment = sat;
  492. // or try
  493. //saturation.input[0] = tex;
  494. //saturation.input[1] = sat;
  495. mtl.color = saturation;
  496. mtl.environment = new THREE.NodeCubeTexture(cubemap); // optional
  497. // GUI
  498. addGui( 'saturation', sat.number, function( val ) {
  499. sat.number = val;
  500. }, false, 0, 2 );
  501. break;
  502. case 'top-bottom':
  503. // MATERIAL
  504. mtl = new THREE.NodePhongMaterial();
  505. var top = new THREE.NodeTexture(grass);
  506. var bottom = new THREE.NodeTexture(brick);
  507. var normal = new THREE.NodeNormal( THREE.NodeNormal.WORLD );
  508. var normalY = new THREE.NodeSwitch(normal, 'y');
  509. var hard = new THREE.NodeFloat(9);
  510. var offset = new THREE.NodeFloat(-2.5);
  511. var hardClamp = new THREE.NodeOperator(
  512. normalY,
  513. hard,
  514. THREE.NodeOperator.MUL
  515. );
  516. var offsetClamp = new THREE.NodeOperator(
  517. hardClamp,
  518. offset,
  519. THREE.NodeOperator.ADD
  520. );
  521. var clamp0at1 = new THREE.NodeMath1( offsetClamp, THREE.NodeMath1.SAT );
  522. var blend = new THREE.NodeMath3(top,bottom,clamp0at1,THREE.NodeMath3.MIX);
  523. mtl.color = blend;
  524. // GUI
  525. addGui( 'hard', hard.number, function( val ) {
  526. hard.number = val;
  527. }, false, 0, 20 );
  528. addGui( 'offset', offset.number, function( val ) {
  529. offset.number = val;
  530. }, false, -10, 10 );
  531. break;
  532. case 'displace':
  533. // MATERIAL
  534. mtl = new THREE.NodePhongMaterial();
  535. var time = new THREE.NodeTime();
  536. var scale = new THREE.NodeFloat(2);
  537. var speed = new THREE.NodeFloat(.2);
  538. var colorA = new THREE.NodeColor(0xFFFFFF);
  539. var colorB = new THREE.NodeColor(0x0054df);
  540. var uv = new THREE.NodeUV();
  541. var timeScl = new THREE.NodeOperator(
  542. time,
  543. speed,
  544. THREE.NodeOperator.MUL
  545. );
  546. var displaceOffset = new THREE.NodeOperator(
  547. timeScl,
  548. uv,
  549. THREE.NodeOperator.ADD
  550. );
  551. var tex = new THREE.NodeTexture(cloud, displaceOffset);
  552. var texArea = new THREE.NodeSwitch(tex, 'w');
  553. var displace = new THREE.NodeOperator(
  554. new THREE.NodeNormal(),
  555. texArea,
  556. THREE.NodeOperator.MUL
  557. );
  558. var displaceScale = new THREE.NodeOperator(
  559. displace,
  560. scale,
  561. THREE.NodeOperator.MUL
  562. );
  563. var blend = new THREE.NodeOperator(
  564. new THREE.NodePosition(),
  565. displaceScale,
  566. THREE.NodeOperator.ADD
  567. );
  568. var color = new THREE.NodeMath3(
  569. colorB,
  570. colorA,
  571. texArea,
  572. THREE.NodeMath3.MIX
  573. );
  574. mtl.color = mtl.specular = new THREE.NodeColor(0);
  575. mtl.emissive = color;
  576. mtl.transform = blend;
  577. // GUI
  578. addGui( 'speed', speed.number, function( val ) {
  579. speed.number = val;
  580. }, false, 0, 1 );
  581. addGui( 'scale', scale.number, function( val ) {
  582. scale.number = val;
  583. }, false, 0, 10 );
  584. addGui( 'colorA', colorA.value.getHex(), function( val ) {
  585. colorA.value.setHex( val );
  586. }, true );
  587. addGui( 'colorB', colorB.value.getHex(), function( val ) {
  588. colorB.value.setHex( val );
  589. }, true );
  590. break;
  591. case 'smoke':
  592. // MATERIAL
  593. mtl = new THREE.NodePhongMaterial();
  594. var time = new THREE.NodeTime();
  595. var uv = new THREE.NodeUV();
  596. var timeSpeedA = new THREE.NodeOperator(
  597. time,
  598. new THREE.NodeVector2(0.3, 0.1),
  599. THREE.NodeOperator.MUL
  600. );
  601. var timeSpeedB = new THREE.NodeOperator(
  602. time,
  603. new THREE.NodeVector2(0.15, 0.4),
  604. THREE.NodeOperator.MUL
  605. );
  606. var uvOffsetA = new THREE.NodeOperator(
  607. timeSpeedA,
  608. uv,
  609. THREE.NodeOperator.ADD
  610. );
  611. var uvOffsetB = new THREE.NodeOperator(
  612. timeSpeedB,
  613. uv,
  614. THREE.NodeOperator.ADD
  615. );
  616. var cloudA = new THREE.NodeTexture(cloud, uvOffsetA);
  617. var cloudB = new THREE.NodeTexture(cloud, uvOffsetB);
  618. var clouds = new THREE.NodeOperator(
  619. cloudA,
  620. cloudB,
  621. THREE.NodeOperator.ADD
  622. );
  623. mtl.environment = new THREE.NodeColor(0xFFFFFF);
  624. mtl.alpha = clouds;
  625. // GUI
  626. addGui( 'color', mtl.environment.value.getHex(), function( val ) {
  627. mtl.environment.value.setHex( val );
  628. }, true );
  629. break;
  630. case 'camera-depth':
  631. // MATERIAL
  632. var colorA = new THREE.NodeColor(0xFFFFFF);
  633. var colorB = new THREE.NodeColor(0x0054df);
  634. var depth = new THREE.NodeCamera( THREE.NodeCamera.DEPTH );
  635. depth.near.number = 1;
  636. depth.far.number = 200;
  637. var colors = new THREE.NodeMath3(
  638. colorB,
  639. colorA,
  640. depth,
  641. THREE.NodeMath3.MIX
  642. );
  643. mtl = new THREE.NodePhongMaterial();
  644. mtl.color = colors;
  645. // GUI
  646. addGui( 'near', depth.near.number, function( val ) {
  647. depth.near.number = val;
  648. }, false, 1, 1200 );
  649. addGui( 'far', depth.far.number, function( val ) {
  650. depth.far.number = val;
  651. }, false, 1, 1200 );
  652. addGui( 'nearColor', colorA.value.getHex(), function( val ) {
  653. colorA.value.setHex( val );
  654. }, true );
  655. addGui( 'farColor', colorB.value.getHex(), function( val ) {
  656. colorB.value.setHex( val );
  657. }, true );
  658. break;
  659. case 'caustic':
  660. // MATERIAL
  661. mtl = new THREE.NodeStandardMaterial();
  662. var hash2 = new THREE.NodeFunction([
  663. "vec2 hash2(vec2 p) {",
  664. "return fract(sin(vec2(dot(p, vec2(123.4, 748.6)), dot(p, vec2(547.3, 659.3))))*5232.85324);",
  665. "}"
  666. ].join( "\n" ));
  667. var voronoi = new THREE.NodeFunction([
  668. // Based off of iq's described here: http://www.iquilezles.org/www/articles/voronoili
  669. "float voronoi(vec2 p, in float time) {",
  670. "vec2 n = floor(p);",
  671. "vec2 f = fract(p);",
  672. "float md = 5.0;",
  673. "vec2 m = vec2(0.0);",
  674. "for (int i = -1; i <= 1; i++) {",
  675. "for (int j = -1; j <= 1; j++) {",
  676. "vec2 g = vec2(i, j);",
  677. "vec2 o = hash2(n + g);",
  678. "o = 0.5 + 0.5 * sin(time + 5.038 * o);",
  679. "vec2 r = g + o - f;",
  680. "float d = dot(r, r);",
  681. "if (d < md) {",
  682. "md = d;",
  683. "m = n+g+o;",
  684. "}",
  685. "}",
  686. "}",
  687. "return md;",
  688. "}"
  689. ].join( "\n" ), [hash2]); // define hash2 as dependencies
  690. var voronoiLayers = new THREE.NodeFunction([
  691. // based on https://www.shadertoy.com/view/4tXSDf
  692. "float voronoiLayers(vec2 p, in float time) {",
  693. "float v = 0.0;",
  694. "float a = 0.4;",
  695. "for (int i = 0; i < 3; i++) {",
  696. "v += voronoi(p, time) * a;",
  697. "p *= 2.0;",
  698. "a *= 0.5;",
  699. "}",
  700. "return v;",
  701. "}"
  702. ].join( "\n" ), [voronoi]); // define voronoi as dependencies
  703. var time = new THREE.NodeTime();
  704. var timeScale = new THREE.NodeFloat(2);
  705. var alpha = new THREE.NodeFloat(1);
  706. var scale = new THREE.NodeFloat(.1);
  707. var intensity = new THREE.NodeFloat(1.5);
  708. var color = new THREE.NodeColor(0xFFFFFF);
  709. var colorA = new THREE.NodeColor(0xFFFFFF);
  710. var colorB = new THREE.NodeColor(0x0054df);
  711. var worldPos = new THREE.NodePosition( THREE.NodePosition.WORLD );
  712. var worldPosTop = new THREE.NodeSwitch(worldPos, 'xz');
  713. var pos = new THREE.NodePosition( THREE.NodePosition.WORLD );
  714. var posNorm = new THREE.NodeMath1(pos, THREE.NodeMath1.NORMALIZE);
  715. var mask = new THREE.NodeSwitch(posNorm, 'y');
  716. // clamp0at1
  717. mask = new THREE.NodeMath1( mask, THREE.NodeMath1.SAT );
  718. var timeOffset = new THREE.NodeOperator(
  719. time,
  720. timeScale,
  721. THREE.NodeOperator.MUL
  722. );
  723. var uvPos = new THREE.NodeOperator(
  724. worldPosTop,
  725. scale,
  726. THREE.NodeOperator.MUL
  727. );
  728. var voronoi = new THREE.NodeFunctionCall(voronoiLayers);
  729. voronoi.input.p = uvPos;
  730. voronoi.input.time = timeOffset;
  731. var maskCaustic = new THREE.NodeOperator(
  732. alpha,
  733. mask,
  734. THREE.NodeOperator.MUL
  735. );
  736. var voronoiIntensity = new THREE.NodeOperator(
  737. voronoi,
  738. intensity,
  739. THREE.NodeOperator.MUL
  740. );
  741. var voronoiColors = new THREE.NodeMath3(
  742. colorB,
  743. colorA,
  744. new THREE.NodeMath1( voronoiIntensity, THREE.NodeMath1.SAT ), // mix needs clamp
  745. THREE.NodeMath3.MIX
  746. );
  747. var caustic = new THREE.NodeMath3(
  748. color,
  749. voronoiColors,
  750. maskCaustic,
  751. THREE.NodeMath3.MIX
  752. );
  753. var causticLights = new THREE.NodeOperator(
  754. voronoiIntensity,
  755. maskCaustic,
  756. THREE.NodeOperator.MUL
  757. );
  758. mtl.color = caustic;
  759. mtl.ambient = causticLights;
  760. // GUI
  761. addGui( 'timeScale', timeScale.number, function( val ) {
  762. timeScale.number = val;
  763. }, false, 0, 5 );
  764. addGui( 'intensity', intensity.number, function( val ) {
  765. intensity.number = val;
  766. }, false, 0, 3 );
  767. addGui( 'scale', scale.number, function( val ) {
  768. scale.number = val;
  769. }, false, 0, 1 );
  770. addGui( 'alpha', alpha.number, function( val ) {
  771. alpha.number = val;
  772. }, false, 0, 1 );
  773. addGui( 'color', color.value.getHex(), function( val ) {
  774. color.value.setHex( val );
  775. }, true );
  776. addGui( 'colorA', colorA.value.getHex(), function( val ) {
  777. colorA.value.setHex( val );
  778. }, true );
  779. addGui( 'colorB', colorB.value.getHex(), function( val ) {
  780. colorB.value.setHex( val );
  781. }, true );
  782. break;
  783. case 'soft-body':
  784. // MATERIAL
  785. move = true;
  786. mtl = new THREE.NodeStandardMaterial();
  787. var scale = new THREE.NodeFloat(2);
  788. var colorA = new THREE.NodeColor(0xFF6633);
  789. var colorB = new THREE.NodeColor(0x3366FF);
  790. var pos = new THREE.NodePosition();
  791. var posNorm = new THREE.NodeMath1(pos, THREE.NodeMath1.NORMALIZE);
  792. var mask = new THREE.NodeSwitch(posNorm, 'y');
  793. var velocity = new THREE.NodeVelocity( mesh, {
  794. type:'elastic',
  795. spring:.8,
  796. friction:.9
  797. } );
  798. var velocityArea = new THREE.NodeOperator(
  799. mask,
  800. scale,
  801. THREE.NodeOperator.MUL
  802. );
  803. var softVelocity = new THREE.NodeOperator(
  804. velocity,
  805. velocityArea,
  806. THREE.NodeOperator.MUL
  807. );
  808. var softPosition = new THREE.NodeOperator(
  809. new THREE.NodePosition(),
  810. softVelocity,
  811. THREE.NodeOperator.ADD
  812. );
  813. var colors = new THREE.NodeMath3(
  814. colorB,
  815. colorA,
  816. mask,
  817. THREE.NodeMath3.MIX
  818. );
  819. mtl.color = colors;
  820. mtl.transform = softPosition;
  821. // GUI
  822. addGui( 'spring', velocity.params.spring, function( val ) {
  823. velocity.params.spring = val;
  824. }, false, 0, .9 );
  825. addGui( 'friction', velocity.params.friction, function( val ) {
  826. velocity.params.friction = val;
  827. }, false, 0, .9 );
  828. addGui( 'scale', scale.number, function( val ) {
  829. scale.number = val;
  830. }, false, 0, 3 );
  831. addGui( 'softBody', colorA.value.getHex(), function( val ) {
  832. colorA.value.setHex( val );
  833. }, true );
  834. addGui( 'hardBody', colorB.value.getHex(), function( val ) {
  835. colorB.value.setHex( val );
  836. }, true );
  837. break;
  838. case 'firefly':
  839. // MATERIAL
  840. mtl = new THREE.NodePhongMaterial();
  841. var time = new THREE.NodeTime();
  842. var speed = new THREE.NodeFloat(.5);
  843. var color = new THREE.NodeColor(0x98ff00);
  844. var timeSpeed = new THREE.NodeOperator(
  845. time,
  846. speed,
  847. THREE.NodeOperator.MUL
  848. );
  849. var sinCycleInSecs = new THREE.NodeOperator(
  850. timeSpeed,
  851. new THREE.NodeConst( THREE.NodeConst.PI2 ),
  852. THREE.NodeOperator.MUL
  853. );
  854. var cycle = new THREE.NodeMath1(sinCycleInSecs, THREE.NodeMath1.SIN);
  855. var cycleColor = new THREE.NodeOperator(
  856. cycle,
  857. color,
  858. THREE.NodeOperator.MUL
  859. );
  860. var cos = new THREE.NodeMath1(cycleColor, THREE.NodeMath1.SIN);
  861. mtl.color = new THREE.NodeColor(0);
  862. mtl.emissive = cos;
  863. // GUI
  864. addGui( 'speed', speed.number, function( val ) {
  865. speed.number = val;
  866. }, false, 0, 3 );
  867. break;
  868. }
  869. // build shader
  870. mtl.build();
  871. // set material
  872. mesh.material = mtl;
  873. }
  874. function onWindowResize() {
  875. camera.aspect = window.innerWidth / window.innerHeight;
  876. camera.updateProjectionMatrix();
  877. renderer.setSize( window.innerWidth, window.innerHeight );
  878. }
  879. function animate() {
  880. var delta = clock.getDelta();
  881. if (move) {
  882. var time = Date.now() * 0.005;
  883. mesh.position.z = Math.cos( time ) * 10;
  884. mesh.position.y = Math.sin( time ) * 10;
  885. }
  886. else {
  887. mesh.position.z = mesh.position.y = 0;
  888. }
  889. //mesh.rotation.z += .01;
  890. // update material animation and/or gpu calcs (pre-renderer)
  891. mesh.material.updateAnimation( delta );
  892. renderer.render( scene, camera );
  893. requestAnimationFrame( animate );
  894. }
  895. </script>
  896. </body>
  897. </html>