123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320 |
- <!doctype html>
- <html lang="en">
- <head>
- <title>WebGL NodeMaterial</title>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
- <style>
- body {
- color: #fff;
- font-family:Monospace;
- font-size:13px;
- margin: 0px;
- text-align:center;
- overflow: hidden;
- }
- #info {
- color: #fff;
- position: absolute;
- top: 10px;
- width: 100%;
- text-align: center;
- display:block;
- }
- a { color: white }
- </style>
- </head>
- <body>
- <div id="container"></div>
- <div id="info">
- <a href="http://threejs.org" target="_blank">three.js</a> - Node-Based Material
- </div>
- <script src="../build/three.min.js"></script>
- <script src='js/geometries/TeapotBufferGeometry.js'></script>
- <script src="js/controls/OrbitControls.js"></script>
- <script src="js/libs/dat.gui.min.js"></script>
- <!-- NodeLibrary -->
- <script src="js/nodes/GLNode.js"></script>
- <script src="js/nodes/RawNode.js"></script>
- <script src="js/nodes/TempNode.js"></script>
- <script src="js/nodes/InputNode.js"></script>
- <script src="js/nodes/ConstNode.js"></script>
- <script src="js/nodes/FunctionNode.js"></script>
- <script src="js/nodes/FunctionCallNode.js"></script>
- <script src="js/nodes/BuilderNode.js"></script>
- <script src="js/nodes/LibNode.js"></script>
- <script src="js/nodes/NodeMaterial.js"></script>
- <!-- Accessors -->
- <script src="js/nodes/accessors/PositionNode.js"></script>
- <script src="js/nodes/accessors/NormalNode.js"></script>
- <script src="js/nodes/accessors/UVNode.js"></script>
- <script src="js/nodes/accessors/ColorsNode.js"></script>
- <script src="js/nodes/accessors/CameraNode.js"></script>
- <script src="js/nodes/accessors/ReflectNode.js"></script>
- <!-- Inputs -->
- <script src="js/nodes/inputs/IntNode.js"></script>
- <script src="js/nodes/inputs/FloatNode.js"></script>
- <script src="js/nodes/inputs/ColorNode.js"></script>
- <script src="js/nodes/inputs/Vector2Node.js"></script>
- <script src="js/nodes/inputs/Vector3Node.js"></script>
- <script src="js/nodes/inputs/Vector4Node.js"></script>
- <script src="js/nodes/inputs/TextureNode.js"></script>
- <script src="js/nodes/inputs/CubeTextureNode.js"></script>
- <!-- Math -->
- <script src="js/nodes/math/Math1Node.js"></script>
- <script src="js/nodes/math/Math2Node.js"></script>
- <script src="js/nodes/math/Math3Node.js"></script>
- <script src="js/nodes/math/OperatorNode.js"></script>
- <!-- Utils -->
- <script src="js/nodes/utils/SwitchNode.js"></script>
- <script src="js/nodes/utils/JoinNode.js"></script>
- <script src="js/nodes/utils/ClockNode.js"></script>
- <script src="js/nodes/utils/RoughnessToBlinnExponentNode.js"></script>
- <script src="js/nodes/utils/VelocityNode.js"></script>
- <!-- Phong Material -->
- <script src="js/nodes/materials/PhongNode.js"></script>
- <script src="js/nodes/materials/PhongNodeMaterial.js"></script>
- <!-- Standard Material -->
- <script src="js/nodes/materials/StandardNode.js"></script>
- <script src="js/nodes/materials/StandardNodeMaterial.js"></script>
- <script>
- var container = document.getElementById( 'container' );
- var renderer, scene, camera, clock = new THREE.Clock(), fov = 50;
- var teapot, mesh;
- var controls;
- var move = false;
- var gui, guiElements = [];
- var param = { example: 'standard' };
- var brick = new THREE.TextureLoader().load( 'textures/brick_diffuse.jpg' );
- var grass = new THREE.TextureLoader().load( 'textures/terrain/grasslight-big.jpg' );
- var grassNormal = new THREE.TextureLoader().load( 'textures/terrain/grasslight-big-nm.jpg' );
- var decalDiffuse = new THREE.TextureLoader().load( 'textures/decal/decal-diffuse.png' );
- decalDiffuse.wrapS = decalDiffuse.wrapT = THREE.RepeatWrapping;
- var cloud = new THREE.TextureLoader().load( 'textures/lava/cloud.png' );
- cloud.wrapS = cloud.wrapT = THREE.RepeatWrapping;
- var cubemap = function() {
- var path = "textures/cube/Park2/";
- var format = '.jpg';
- var urls = [
- path + 'posx' + format, path + 'negx' + format,
- path + 'posy' + format, path + 'negy' + format,
- path + 'posz' + format, path + 'negz' + format
- ];
- var textureCube = new THREE.CubeTextureLoader().load( urls );
- textureCube.format = THREE.RGBFormat;
- return textureCube;
- }();
- window.addEventListener( 'load', init );
- function init() {
- renderer = new THREE.WebGLRenderer( { antialias: true } );
- renderer.setPixelRatio( window.devicePixelRatio );
- renderer.setSize( window.innerWidth, window.innerHeight );
- container.appendChild( renderer.domElement );
- scene = new THREE.Scene();
- camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1000 );
- camera.position.x = 50;
- camera.position.z = - 50;
- camera.position.y = 30;
- camera.target = new THREE.Vector3();
- controls = new THREE.OrbitControls( camera, renderer.domElement );
- controls.minDistance = 50;
- controls.maxDistance = 200;
- scene.add( new THREE.AmbientLight( 0x464646 ) );
- var light = new THREE.DirectionalLight( 0xffddcc, 1 );
- light.position.set( 1, 0.75, 0.5 );
- scene.add( light );
- var light = new THREE.DirectionalLight( 0xccccff, 1 );
- light.position.set( - 1, 0.75, - 0.5 );
- scene.add( light );
- teapot = new THREE.TeapotBufferGeometry( 15, 18 );
- mesh = new THREE.Mesh( teapot );
- scene.add( mesh );
- window.addEventListener( 'resize', onWindowResize, false );
- updateMaterial();
- onWindowResize();
- animate();
- }
- function clearGui() {
- if ( gui ) gui.destroy();
- gui = new dat.GUI();
- var example = gui.add( param, 'example', {
- 'basic / standard (PBR)': 'standard',
- 'basic / phong': 'phong',
- 'basic / layers': 'layers',
- 'basic / rim': 'rim',
- 'adv / fresnel': 'fresnel',
- 'adv / saturation': 'saturation',
- 'adv / top-bottom': 'top-bottom',
- 'adv / caustic': 'caustic',
- 'adv / displace': 'displace',
- 'adv / camera-depth': 'camera-depth',
- 'adv / soft-body': 'soft-body',
- 'adv / wave': 'wave',
- 'misc / smoke' : 'smoke',
- 'misc / firefly' : 'firefly'
- } ).onFinishChange( function() {
- updateMaterial();
- } );
- gui.open();
- }
- function addGui( name, value, callback, isColor, min, max ) {
- var node;
- param[ name ] = value;
- if ( isColor ) {
- node = gui.addColor( param, name ).onChange( function() {
- callback( param[ name ] );
- } );
- }
- else if (typeof value == 'object') {
- node = gui.add( param, name, value ).onChange( function() {
- callback( param[ name ] );
- } );
- }
- else {
- node = gui.add( param, name, min, max ).onChange( function() {
- callback( param[ name ] );
- } );
- }
- return node;
- }
- function updateMaterial() {
- move = false;
- if ( mesh.material ) mesh.material.dispose();
- var name = param.example;
- var mtl;
- clearGui();
- switch ( name ) {
- case 'phong':
- // MATERIAL
- mtl = new THREE.PhongNodeMaterial();
- //mtl.color = // albedo color
- //mtl.alpha = // opacity (0 at 1)
- //mtl.specular = // specular color
- //mtl.shininess = // shininess (float)
- //mtl.normal = // normalmap
- //mtl.normalScale = // normalmap scale
- //mtl.emissive = // emissive color
- //mtl.ambient = // ambient color
- //mtl.shadow = // shadowmap
- //mtl.ao = // ambient occlusion
- //mtl.environment = // reflection map (CubeMap recommended)
- //mtl.reflectivity = // environment intensity
- //mtl.transform = // vertex transformation
- var mask = new THREE.SwitchNode( new THREE.TextureNode( decalDiffuse ), 'w' );
- mtl.color = new THREE.TextureNode( grass );
- mtl.specular = new THREE.FloatNode( .5 );
- mtl.shininess = new THREE.FloatNode( 15 );
- mtl.environment = new THREE.CubeTextureNode( cubemap );
- mtl.reflectivity = mask;
- mtl.normal = new THREE.TextureNode( grassNormal );
- mtl.normalScale = new THREE.Math1Node( mask, THREE.Math1Node.INVERT );
- break;
- case 'standard':
- // MATERIAL
- mtl = new THREE.StandardNodeMaterial();
- //mtl.color = // albedo color
- //mtl.alpha = // opacity (0 at 1)
- //mtl.roughness = // roughness (float)
- //mtl.metalness = // metalness (float)
- //mtl.normal = // normalmap
- //mtl.normalScale = // normalmap scale
- //mtl.emissive = // emissive color
- //mtl.ambient = // ambient color
- //mtl.shadow = // shadowmap
- //mtl.ao = // ambient occlusion
- //mtl.environment = // reflection map (CubeMap recommended)
- //mtl.reflectivity = // environment intensity
- //mtl.transform = // vertex transformation
- var mask = new THREE.SwitchNode( new THREE.TextureNode( decalDiffuse ), 'w' );
- var normalScale = new THREE.FloatNode( .3 );
- var roughnessA = new THREE.FloatNode( .5 );
- var metalnessA = new THREE.FloatNode( .5 );
- var roughnessB = new THREE.FloatNode( 0 );
- var metalnessB = new THREE.FloatNode( 1 );
- var roughness = new THREE.Math3Node(
- roughnessA,
- roughnessB,
- mask,
- THREE.Math3Node.MIX
- );
- var metalness = new THREE.Math3Node(
- metalnessA,
- metalnessB,
- mask,
- THREE.Math3Node.MIX
- );
- var normalMask = new THREE.OperatorNode(
- new THREE.Math1Node( mask, THREE.Math1Node.INVERT ),
- normalScale,
- THREE.OperatorNode.MUL
- );
- mtl.color = new THREE.ColorNode( 0xFFFFFF );
- mtl.roughness = roughness;
- mtl.metalness = metalness;
- mtl.environment = new THREE.CubeTextureNode( cubemap );
- mtl.normal = new THREE.TextureNode( grassNormal );
- mtl.normalScale = normalMask;
- // GUI
- addGui( 'color', mtl.color.value.getHex(), function( val ) {
- mtl.color.value.setHex( val );
- }, true );
- addGui( 'roughnessA', roughnessA.number, function( val ) {
- roughnessA.number = val;
- }, false, 0, 1 );
- addGui( 'metalnessA', metalnessA.number, function( val ) {
- metalnessA.number = val;
- }, false, 0, 1 );
- addGui( 'roughnessB', roughnessB.number, function( val ) {
- roughnessB.number = val;
- }, false, 0, 1 );
- addGui( 'metalnessB', metalnessB.number, function( val ) {
- metalnessB.number = val;
- }, false, 0, 1 );
- addGui( 'normalScale', normalScale.number, function( val ) {
- normalScale.number = val;
- }, false, 0, 1 );
- break;
- case 'wave':
- // MATERIAL
- mtl = new THREE.PhongNodeMaterial();
- var time = new THREE.ClockNode();
- var speed = new THREE.FloatNode( 5 );
- var scale = new THREE.FloatNode( 1 );
- var worldScale = new THREE.FloatNode( .4 );
- var colorA = new THREE.ColorNode( 0xFFFFFF );
- var colorB = new THREE.ColorNode( 0x0054df );
- var uv = new THREE.UVNode();
- var timeScale = new THREE.OperatorNode(
- time,
- speed,
- THREE.OperatorNode.MUL
- );
- var worldScl = new THREE.OperatorNode(
- new THREE.PositionNode(),
- worldScale,
- THREE.OperatorNode.MUL
- );
- var posContinuous = new THREE.OperatorNode(
- worldScl,
- timeScale,
- THREE.OperatorNode.ADD
- );
- var wave = new THREE.Math1Node( posContinuous, THREE.Math1Node.SIN );
- wave = new THREE.SwitchNode( wave, 'x' );
- var waveScale = new THREE.OperatorNode(
- wave,
- scale,
- THREE.OperatorNode.MUL
- );
- var displaceY = new THREE.JoinNode(
- new THREE.FloatNode(),
- waveScale,
- new THREE.FloatNode()
- );
- var displace = new THREE.OperatorNode(
- new THREE.NormalNode(),
- displaceY,
- THREE.OperatorNode.MUL
- );
- var blend = new THREE.OperatorNode(
- new THREE.PositionNode(),
- displaceY,
- THREE.OperatorNode.ADD
- );
- var color = new THREE.Math3Node(
- colorB,
- colorA,
- wave,
- THREE.Math3Node.MIX
- );
- mtl.color = color;
- mtl.transform = blend;
- // GUI
- addGui( 'speed', speed.number, function( val ) {
- speed.number = val;
- }, false, 0, 10 );
- addGui( 'scale', scale.number, function( val ) {
- scale.number = val;
- }, false, 0, 3 );
- addGui( 'worldScale', worldScale.number, function( val ) {
- worldScale.number = val;
- }, false, 0, 1 );
- addGui( 'colorA', colorA.value.getHex(), function( val ) {
- colorA.value.setHex( val );
- }, true );
- addGui( 'colorB', colorB.value.getHex(), function( val ) {
- colorB.value.setHex( val );
- }, true );
- addGui( 'useNormals', false, function( val ) {
- blend.b = val ? displace : displaceY;
- mtl.build();
- } );
- break;
- case 'rim':
- // MATERIAL
- mtl = new THREE.PhongNodeMaterial();
- var intensity = 1.3;
- var power = new THREE.FloatNode( 3 );
- var color = new THREE.ColorNode( 0xFFFFFF );
- var viewZ = new THREE.Math2Node(
- new THREE.NormalNode( THREE.NormalNode.VIEW ),
- new THREE.Vector3Node( 0, 0, - intensity ),
- THREE.Math2Node.DOT
- );
- var rim = new THREE.OperatorNode(
- viewZ,
- new THREE.FloatNode( intensity ),
- THREE.OperatorNode.ADD
- );
- var rimPower = new THREE.Math2Node(
- rim,
- power,
- THREE.Math2Node.POW
- );
- var rimColor = new THREE.OperatorNode(
- rimPower,
- color,
- THREE.OperatorNode.MUL
- );
- mtl.color = new THREE.ColorNode( 0x111111 );
- mtl.emissive = rimColor;
- // GUI
- addGui( 'color', color.value.getHex(), function( val ) {
- color.value.setHex( val );
- }, true );
- addGui( 'intensity', intensity, function( val ) {
- intensity = val;
- viewZ.b.z = - intensity;
- rim.b.number = intensity;
- }, false, 0, 3 );
- addGui( 'power', power.number, function( val ) {
- power.number = val;
- }, false, 0, 6 );
- addGui( 'xray', false, function( val ) {
- if ( val ) {
- mtl.emissive = color;
- mtl.alpha = rimPower;
- mtl.blending = THREE.AdditiveBlending;
- mtl.depthWrite = false;
- }
- else {
- mtl.emissive = rimColor;
- mtl.alpha = null;
- mtl.blending = THREE.NormalBlending;
- mtl.depthWrite = true;
- }
- mtl.build();
- } );
- break;
- case 'fresnel':
- // MATERIAL
- mtl = new THREE.PhongNodeMaterial();
- var reflectance = new THREE.FloatNode( 1.3 );
- var power = new THREE.FloatNode( 1 );
- var color = new THREE.CubeTextureNode( cubemap );
- var viewZ = new THREE.Math2Node(
- new THREE.NormalNode( THREE.NormalNode.VIEW ),
- new THREE.Vector3Node( 0, 0, - 1 ),
- THREE.Math2Node.DOT
- );
- var theta = new THREE.OperatorNode(
- viewZ,
- new THREE.FloatNode( 1 ),
- THREE.OperatorNode.ADD
- );
- var thetaPower = new THREE.Math2Node(
- theta,
- power,
- THREE.Math2Node.POW
- );
- var fresnel = new THREE.OperatorNode(
- reflectance,
- thetaPower,
- THREE.OperatorNode.MUL
- );
- mtl.color = new THREE.ColorNode( 0x3399FF );
- mtl.environment = color;
- mtl.reflectivity = new THREE.Math1Node( fresnel, THREE.Math1Node.SAT );
- // GUI
- addGui( 'reflectance', reflectance.number, function( val ) {
- reflectance.number = val;
- }, false, 0, 3 );
- addGui( 'power', power.number, function( val ) {
- power.number = val;
- }, false, 0, 5 );
- break;
- case 'layers':
- // MATERIAL
- mtl = new THREE.PhongNodeMaterial();
- var tex1 = new THREE.TextureNode( grass );
- var tex2 = new THREE.TextureNode( brick );
- var offset = new THREE.FloatNode( 0 );
- var scale = new THREE.FloatNode( 1 );
- var uv = new THREE.UVNode();
- var uvOffset = new THREE.OperatorNode(
- offset,
- uv,
- THREE.OperatorNode.ADD
- );
- var uvScale = new THREE.OperatorNode(
- uvOffset,
- scale,
- THREE.OperatorNode.MUL
- );
- var mask = new THREE.TextureNode( decalDiffuse, uvScale );
- var maskAlphaChannel = new THREE.SwitchNode( mask, 'w' );
- var blend = new THREE.Math3Node(
- tex1,
- tex2,
- maskAlphaChannel,
- THREE.Math3Node.MIX
- );
- mtl.color = blend;
- // GUI
- addGui( 'offset', offset.number, function( val ) {
- offset.number = val;
- }, false, 0, 1 );
- addGui( 'scale', scale.number, function( val ) {
- scale.number = val;
- }, false, 0, 10 );
- break;
- case 'saturation':
- // MATERIAL
- mtl = new THREE.StandardNodeMaterial();
- var tex = new THREE.TextureNode( brick );
- var sat = new THREE.FloatNode( 0 );
- var satrgb = new THREE.FunctionNode( [
- "vec3 satrgb(vec3 rgb, float adjustment) {",
- //"const vec3 W = vec3(0.2125, 0.7154, 0.0721);", // LUMA
- "vec3 intensity = vec3(dot(rgb, LUMA));",
- "return mix(intensity, rgb, adjustment);",
- "}"
- ].join( "\n" ) );
- var saturation = new THREE.FunctionCallNode( satrgb );
- saturation.inputs.rgb = tex;
- saturation.inputs.adjustment = sat;
- // or try
- //saturation.inputs[0] = tex;
- //saturation.inputs[1] = sat;
- mtl.color = saturation;
- mtl.environment = new THREE.CubeTextureNode( cubemap ); // optional
- // GUI
- addGui( 'saturation', sat.number, function( val ) {
- sat.number = val;
- }, false, 0, 2 );
- break;
- case 'top-bottom':
- // MATERIAL
- mtl = new THREE.PhongNodeMaterial();
- var top = new THREE.TextureNode( grass );
- var bottom = new THREE.TextureNode( brick );
- var normal = new THREE.NormalNode( THREE.NormalNode.WORLD );
- var normalY = new THREE.SwitchNode( normal, 'y' );
- var hard = new THREE.FloatNode( 9 );
- var offset = new THREE.FloatNode( - 2.5 );
- var hardClamp = new THREE.OperatorNode(
- normalY,
- hard,
- THREE.OperatorNode.MUL
- );
- var offsetClamp = new THREE.OperatorNode(
- hardClamp,
- offset,
- THREE.OperatorNode.ADD
- );
- var clamp0at1 = new THREE.Math1Node( offsetClamp, THREE.Math1Node.SAT );
- var blend = new THREE.Math3Node( top, bottom, clamp0at1, THREE.Math3Node.MIX );
- mtl.color = blend;
- // GUI
- addGui( 'hard', hard.number, function( val ) {
- hard.number = val;
- }, false, 0, 20 );
- addGui( 'offset', offset.number, function( val ) {
- offset.number = val;
- }, false, - 10, 10 );
- break;
- case 'displace':
- // MATERIAL
- mtl = new THREE.PhongNodeMaterial();
- var time = new THREE.ClockNode();
- var scale = new THREE.FloatNode( 2 );
- var speed = new THREE.FloatNode( .2 );
- var colorA = new THREE.ColorNode( 0xFFFFFF );
- var colorB = new THREE.ColorNode( 0x0054df );
- var uv = new THREE.UVNode();
- var timeScl = new THREE.OperatorNode(
- time,
- speed,
- THREE.OperatorNode.MUL
- );
- var displaceOffset = new THREE.OperatorNode(
- timeScl,
- uv,
- THREE.OperatorNode.ADD
- );
- var tex = new THREE.TextureNode( cloud, displaceOffset );
- var texArea = new THREE.SwitchNode( tex, 'w' );
- var displace = new THREE.OperatorNode(
- new THREE.NormalNode(),
- texArea,
- THREE.OperatorNode.MUL
- );
- var displaceScale = new THREE.OperatorNode(
- displace,
- scale,
- THREE.OperatorNode.MUL
- );
- var blend = new THREE.OperatorNode(
- new THREE.PositionNode(),
- displaceScale,
- THREE.OperatorNode.ADD
- );
- var color = new THREE.Math3Node(
- colorB,
- colorA,
- texArea,
- THREE.Math3Node.MIX
- );
- mtl.color = mtl.specular = new THREE.ColorNode( 0 );
- mtl.emissive = color;
- mtl.transform = blend;
- // GUI
- addGui( 'speed', speed.number, function( val ) {
- speed.number = val;
- }, false, 0, 1 );
- addGui( 'scale', scale.number, function( val ) {
- scale.number = val;
- }, false, 0, 10 );
- addGui( 'colorA', colorA.value.getHex(), function( val ) {
- colorA.value.setHex( val );
- }, true );
- addGui( 'colorB', colorB.value.getHex(), function( val ) {
- colorB.value.setHex( val );
- }, true );
- break;
- case 'smoke':
- // MATERIAL
- mtl = new THREE.PhongNodeMaterial();
- var time = new THREE.ClockNode();
- var uv = new THREE.UVNode();
- var timeSpeedA = new THREE.OperatorNode(
- time,
- new THREE.Vector2Node( 0.3, 0.1 ),
- THREE.OperatorNode.MUL
- );
- var timeSpeedB = new THREE.OperatorNode(
- time,
- new THREE.Vector2Node( 0.15, 0.4 ),
- THREE.OperatorNode.MUL
- );
- var uvOffsetA = new THREE.OperatorNode(
- timeSpeedA,
- uv,
- THREE.OperatorNode.ADD
- );
- var uvOffsetB = new THREE.OperatorNode(
- timeSpeedB,
- uv,
- THREE.OperatorNode.ADD
- );
- var cloudA = new THREE.TextureNode( cloud, uvOffsetA );
- var cloudB = new THREE.TextureNode( cloud, uvOffsetB );
- var clouds = new THREE.OperatorNode(
- cloudA,
- cloudB,
- THREE.OperatorNode.ADD
- );
- mtl.environment = new THREE.ColorNode( 0xFFFFFF );
- mtl.alpha = clouds;
- // GUI
- addGui( 'color', mtl.environment.value.getHex(), function( val ) {
- mtl.environment.value.setHex( val );
- }, true );
- break;
- case 'camera-depth':
- // MATERIAL
- var colorA = new THREE.ColorNode( 0xFFFFFF );
- var colorB = new THREE.ColorNode( 0x0054df );
- var depth = new THREE.CameraNode( THREE.CameraNode.DEPTH );
- depth.near.number = 1;
- depth.far.number = 200;
- var colors = new THREE.Math3Node(
- colorB,
- colorA,
- depth,
- THREE.Math3Node.MIX
- );
- mtl = new THREE.PhongNodeMaterial();
- mtl.color = colors;
- // GUI
- addGui( 'near', depth.near.number, function( val ) {
- depth.near.number = val;
- }, false, 1, 1200 );
- addGui( 'far', depth.far.number, function( val ) {
- depth.far.number = val;
- }, false, 1, 1200 );
- addGui( 'nearColor', colorA.value.getHex(), function( val ) {
- colorA.value.setHex( val );
- }, true );
- addGui( 'farColor', colorB.value.getHex(), function( val ) {
- colorB.value.setHex( val );
- }, true );
- break;
- case 'caustic':
- // MATERIAL
- mtl = new THREE.StandardNodeMaterial();
- var hash2 = new THREE.FunctionNode( [
- "vec2 hash2(vec2 p) {",
- "return fract(sin(vec2(dot(p, vec2(123.4, 748.6)), dot(p, vec2(547.3, 659.3))))*5232.85324);",
- "}"
- ].join( "\n" ) );
- var voronoi = new THREE.FunctionNode( [
- // Based off of iq's described here: http://www.iquilezles.org/www/articles/voronoili
- "float voronoi(vec2 p, in float time) {",
- "vec2 n = floor(p);",
- "vec2 f = fract(p);",
- "float md = 5.0;",
- "vec2 m = vec2(0.0);",
- "for (int i = -1; i <= 1; i++) {",
- "for (int j = -1; j <= 1; j++) {",
- "vec2 g = vec2(i, j);",
- "vec2 o = hash2(n + g);",
- "o = 0.5 + 0.5 * sin(time + 5.038 * o);",
- "vec2 r = g + o - f;",
- "float d = dot(r, r);",
- "if (d < md) {",
- "md = d;",
- "m = n+g+o;",
- "}",
- "}",
- "}",
- "return md;",
- "}"
- ].join( "\n" ), [ hash2 ] ); // define hash2 as dependencies
- var voronoiLayers = new THREE.FunctionNode( [
- // based on https://www.shadertoy.com/view/4tXSDf
- "float voronoiLayers(vec2 p, in float time) {",
- "float v = 0.0;",
- "float a = 0.4;",
- "for (int i = 0; i < 3; i++) {",
- "v += voronoi(p, time) * a;",
- "p *= 2.0;",
- "a *= 0.5;",
- "}",
- "return v;",
- "}"
- ].join( "\n" ), [ voronoi ] ); // define voronoi as dependencies
- var time = new THREE.ClockNode();
- var timeScale = new THREE.FloatNode( 2 );
- var alpha = new THREE.FloatNode( 1 );
- var scale = new THREE.FloatNode( .1 );
- var intensity = new THREE.FloatNode( 1.5 );
- var color = new THREE.ColorNode( 0xFFFFFF );
- var colorA = new THREE.ColorNode( 0xFFFFFF );
- var colorB = new THREE.ColorNode( 0x0054df );
- var worldPos = new THREE.PositionNode( THREE.PositionNode.WORLD );
- var worldPosTop = new THREE.SwitchNode( worldPos, 'xz' );
- var worldNormal = new THREE.NormalNode( THREE.NormalNode.WORLD );
- var mask = new THREE.SwitchNode( worldNormal, 'y' );
- // clamp0at1
- mask = new THREE.Math1Node( mask, THREE.Math1Node.SAT );
- var timeOffset = new THREE.OperatorNode(
- time,
- timeScale,
- THREE.OperatorNode.MUL
- );
- var uvPos = new THREE.OperatorNode(
- worldPosTop,
- scale,
- THREE.OperatorNode.MUL
- );
- var voronoi = new THREE.FunctionCallNode( voronoiLayers );
- voronoi.inputs.p = uvPos;
- voronoi.inputs.time = timeOffset;
- var maskCaustic = new THREE.OperatorNode(
- alpha,
- mask,
- THREE.OperatorNode.MUL
- );
- var voronoiIntensity = new THREE.OperatorNode(
- voronoi,
- intensity,
- THREE.OperatorNode.MUL
- );
- var voronoiColors = new THREE.Math3Node(
- colorB,
- colorA,
- new THREE.Math1Node( voronoiIntensity, THREE.Math1Node.SAT ), // mix needs clamp
- THREE.Math3Node.MIX
- );
- var caustic = new THREE.Math3Node(
- color,
- voronoiColors,
- maskCaustic,
- THREE.Math3Node.MIX
- );
- var causticLights = new THREE.OperatorNode(
- voronoiIntensity,
- maskCaustic,
- THREE.OperatorNode.MUL
- );
- mtl.color = caustic;
- mtl.ambient = causticLights;
- // GUI
- addGui( 'timeScale', timeScale.number, function( val ) {
- timeScale.number = val;
- }, false, 0, 5 );
- addGui( 'intensity', intensity.number, function( val ) {
- intensity.number = val;
- }, false, 0, 3 );
- addGui( 'scale', scale.number, function( val ) {
- scale.number = val;
- }, false, 0, 1 );
- addGui( 'alpha', alpha.number, function( val ) {
- alpha.number = val;
- }, false, 0, 1 );
- addGui( 'color', color.value.getHex(), function( val ) {
- color.value.setHex( val );
- }, true );
- addGui( 'colorA', colorA.value.getHex(), function( val ) {
- colorA.value.setHex( val );
- }, true );
- addGui( 'colorB', colorB.value.getHex(), function( val ) {
- colorB.value.setHex( val );
- }, true );
- break;
- case 'soft-body':
- // MATERIAL
- move = true;
- mtl = new THREE.StandardNodeMaterial();
- var scale = new THREE.FloatNode( 2 );
- var colorA = new THREE.ColorNode( 0xFF6633 );
- var colorB = new THREE.ColorNode( 0x3366FF );
- var pos = new THREE.PositionNode();
- var posNorm = new THREE.Math1Node( pos, THREE.Math1Node.NORMALIZE );
- var mask = new THREE.SwitchNode( posNorm, 'y' );
- var velocity = new THREE.VelocityNode( mesh, {
- type: 'elastic',
- spring: .8,
- friction: .9
- } );
- var velocityArea = new THREE.OperatorNode(
- mask,
- scale,
- THREE.OperatorNode.MUL
- );
- var softVelocity = new THREE.OperatorNode(
- velocity,
- velocityArea,
- THREE.OperatorNode.MUL
- );
- var softPosition = new THREE.OperatorNode(
- new THREE.PositionNode(),
- softVelocity,
- THREE.OperatorNode.ADD
- );
- var colors = new THREE.Math3Node(
- colorB,
- colorA,
- mask,
- THREE.Math3Node.MIX
- );
- mtl.color = colors;
- mtl.transform = softPosition;
- // GUI
- addGui( 'spring', velocity.params.spring, function( val ) {
- velocity.params.spring = val;
- }, false, 0, .9 );
- addGui( 'friction', velocity.params.friction, function( val ) {
- velocity.params.friction = val;
- }, false, 0, .9 );
- addGui( 'scale', scale.number, function( val ) {
- scale.number = val;
- }, false, 0, 3 );
- addGui( 'softBody', colorA.value.getHex(), function( val ) {
- colorA.value.setHex( val );
- }, true );
- addGui( 'hardBody', colorB.value.getHex(), function( val ) {
- colorB.value.setHex( val );
- }, true );
- break;
- case 'firefly':
- // MATERIAL
- mtl = new THREE.PhongNodeMaterial();
- var time = new THREE.ClockNode();
- var speed = new THREE.FloatNode( .5 );
- var color = new THREE.ColorNode( 0x98ff00 );
- var timeSpeed = new THREE.OperatorNode(
- time,
- speed,
- THREE.OperatorNode.MUL
- );
- var sinCycleInSecs = new THREE.OperatorNode(
- timeSpeed,
- new THREE.ConstNode( THREE.ConstNode.PI2 ),
- THREE.OperatorNode.MUL
- );
- var cycle = new THREE.Math1Node( sinCycleInSecs, THREE.Math1Node.SIN );
- var cycleColor = new THREE.OperatorNode(
- cycle,
- color,
- THREE.OperatorNode.MUL
- );
- var cos = new THREE.Math1Node( cycleColor, THREE.Math1Node.SIN );
- mtl.color = new THREE.ColorNode( 0 );
- mtl.emissive = cos;
- // GUI
- addGui( 'speed', speed.number, function( val ) {
- speed.number = val;
- }, false, 0, 3 );
- break;
- }
- // build shader
- mtl.build();
- // set material
- mesh.material = mtl;
- }
- function onWindowResize() {
- camera.aspect = window.innerWidth / window.innerHeight;
- camera.updateProjectionMatrix();
- renderer.setSize( window.innerWidth, window.innerHeight );
- }
- function animate() {
- var delta = clock.getDelta();
- if ( move ) {
- var time = Date.now() * 0.005;
- mesh.position.z = Math.cos( time ) * 10;
- mesh.position.y = Math.sin( time ) * 10;
- }
- else {
- mesh.position.z = mesh.position.y = 0;
- }
- //mesh.rotation.z += .01;
- // update material animation and/or gpu calcs (pre-renderer)
- mesh.material.updateAnimation( delta );
- renderer.render( scene, camera );
- requestAnimationFrame( animate );
- }
- </script>
- </body>
- </html>
|