| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319 |
- <!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/NodeLib.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/TimerNode.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 (vec3)
- //mtl.alpha = // opacity (float)
- //mtl.specular = // specular color (vec3)
- //mtl.shininess = // shininess (float)
- //mtl.normal = // normalmap (vec3)
- //mtl.normalScale = // normalmap scale (vec2)
- //mtl.emissive = // emissive color (vec3)
- //mtl.ambient = // ambient color (vec3)
- //mtl.shadow = // shadowmap (vec3)
- //mtl.ao = // ambient occlusion (float)
- //mtl.environment = // reflection/refraction (vec3)
- //mtl.environmentAlpha = // environment alpha (float)
- //mtl.transform = // vertex transformation (vec3)
- 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.environmentAlpha = 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 (vec3)
- //mtl.alpha = // opacity (float)
- //mtl.roughness = // roughness (float)
- //mtl.metalness = // metalness (float)
- //mtl.normal = // normalmap (vec3)
- //mtl.normalScale = // normalmap scale (vec2)
- //mtl.emissive = // emissive color (vec3)
- //mtl.ambient = // ambient color (vec3)
- //mtl.shadow = // shadowmap (vec3)
- //mtl.ao = // ambient occlusion (float)
- //mtl.environment = // reflection/refraction (vec3)
- //mtl.transform = // vertex transformation (vec3)
- 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.TimerNode();
- 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.environmentAlpha = 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.TimerNode();
- 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.TimerNode();
- 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.TimerNode();
- 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.TimerNode();
- 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>
|