Name
*
Code
{"properties":{"frame":0,"maxFrame":600,"maxFrameLocked":false,"realtimeState":true,"mainCameraPath":"/perspectiveCamera_MAIN","versions":{"polygonjs":"1.2.21"}},"root":{"type":"root","nodes":{"hemisphereLight1":{"type":"hemisphereLight","flags":{"display":true}},"spotLight1":{"type":"spotLight","params":{"r":[90,0,0],"intensity":3,"angle":50.4,"penumbra":0.6,"decay":0.23,"shadowBias":0,"shadowRadius":60},"inputs":["polarTransform1"],"flags":{"display":true}},"COP":{"type":"copNetwork","nodes":{"envMap":{"type":"envMap","inputs":["imageEnv"]},"imageEnv":{"type":"imageEXR","params":{"url":"https://raw.githubusercontent.com/polygonjs/polygonjs-assets/master/textures/piz_compressed.exr"}},"imageUv":{"type":"image","params":{"url":"https://raw.githubusercontent.com/polygonjs/polygonjs-assets/master/textures/uv.jpg","tflipY":true}}}},"set":{"type":"geo","nodes":{"MAT":{"type":"materialsNetwork","nodes":{"meshStandard1":{"type":"meshStandard","params":{"useEnvMap":true,"envMap":"../../../COP/envMap","roughness":0.87,"useFog":true}}}},"circle1":{"type":"circle","params":{"radius":0.5,"segments":100,"connectLastPoint":false,"arcAngle":90,"direction":[0,0,1]}},"material1":{"type":"material","params":{"material":"../MAT/meshStandard1"},"inputs":["transform9"]},"skin1":{"type":"skin","inputs":["transform6","transform1"]},"transform1":{"type":"transform","params":{"t":["-ch(\"../transform6/tx\")",0,0]},"inputs":["transform5"]},"transform2":{"type":"transform","params":{"t":[0.5,0.5,0],"r":[0,90,-90]},"inputs":["circle1"]},"transform3":{"type":"transform","params":{"t":[0,"-bbox(0, 'min').y",0]},"inputs":["transform2"]},"transform4":{"type":"transform","params":{"group":"0","t":[0,0,50]},"inputs":["transform3"]},"transform5":{"type":"transform","params":{"group":"`pointsCount(0)-1`","t":[0,50,0]},"inputs":["transform4"]},"transform6":{"type":"transform","params":{"t":[50,0,0]},"inputs":["transform5"]},"transform7":{"type":"transform","params":{"t":[0,0,-1.7127319559331746]},"inputs":["material1"]},"transform8":{"type":"transform","params":{"scale":5.4},"inputs":["transform7"],"flags":{"display":true}},"transform9":{"type":"transform","params":{"s":[4,1,1]},"inputs":["skin1"]}},"flags":{"display":true}},"polarTransform1":{"type":"polarTransform","params":{"longitude":50.4,"latitude":25.2,"depth":15.6},"inputs":["null1"],"flags":{"display":false}},"gridHelper":{"type":"geo","nodes":{"plane1":{"type":"plane"},"planeHelper1":{"type":"planeHelper","flags":{"display":true}}},"flags":{"display":false}},"spotLight2":{"type":"spotLight","params":{"r":[90,0,0],"penumbra":0.4,"decay":0.43,"shadowBias":0,"shadowRadius":7.2},"inputs":["polarTransform2"],"flags":{"display":true}},"polarTransform2":{"type":"polarTransform","params":{"longitude":327.6,"latitude":50.4,"depth":22},"inputs":["null1"],"flags":{"display":false}},"null1":{"type":"null","params":{"t":[0,0,-7.239058048075525]},"flags":{"display":false}},"contactShadow1":{"type":"contactShadow","params":{"t":[-0.7603034971525082,0.3277860273265716,0.5045394655675899],"r":[0,37.843408801064925,0],"dist":6.5,"planeSize":[26.3,6.3],"blur":14,"blur2":30,"darkness":0.78},"flags":{"display":false}},"positionalAudio1":{"type":"positionalAudio","nodes":{"OUT":{"type":"null","inputs":["switch2"]},"Synth1":{"type":"Synth"},"chorus1":{"type":"chorus","params":{"frequency":1.2},"inputs":["monoSynth1"]},"chorus2":{"type":"chorus","params":{"frequency":1.2},"inputs":["pitchShift1"]},"envelope1":{"type":"envelope"},"monoSynth1":{"type":"monoSynth","inputs":["envelope1"]},"pitchShift1":{"type":"pitchShift","params":{"pitch":4},"inputs":["monoSynth1"]},"playInstrument1":{"type":"playInstrument","params":{"note":"B4","startOctave":3,"updateNoteFromInstrument":true},"inputs":["OUT"]},"polySynth1":{"type":"polySynth"},"reverb1":{"type":"reverb","params":{"preDelay":0.06},"inputs":["monoSynth1"]},"reverb2":{"type":"reverb","params":{"decay":5.0005,"preDelay":0.12},"inputs":["monoSynth1"]},"switch1":{"type":"switch","inputs":["monoSynth1"]},"switch2":{"type":"switch","params":{"input":3},"inputs":["volume1","reverb2","chorus1","chorus2"]},"volume1":{"type":"volume","params":{"volume":10.8},"inputs":["reverb1"]}},"params":{"t":[0,4.693410955934931,0],"audioNode":"OUT","showHelper":false},"inputs":["musicBoxes"],"flags":{"display":true}},"audioListener1":{"type":"audioListener","inputs":["perspectiveCamera_MAIN"],"flags":{"display":true}},"musicBoxes":{"type":"geo","nodes":{"ANIM":{"type":"animationsNetwork","nodes":{"PLAY":{"type":"null","inputs":["operation1"]},"PLAY1":{"type":"null","inputs":["operation2"]},"RESET":{"type":"null","inputs":["position2"]},"RESET1":{"type":"null","inputs":["position4"]},"duration1":{"type":"duration","params":{"duration":1.4}},"duration2":{"type":"duration"},"duration3":{"type":"duration","params":{"duration":5.8}},"duration5":{"type":"duration"},"easing1":{"type":"easing","params":{"name":3,"inOut":2},"inputs":["duration5"]},"easing2":{"type":"easing","params":{"name":3,"inOut":2},"inputs":["duration2"]},"easing3":{"type":"easing","params":{"name":7},"inputs":["duration1"]},"easing4":{"type":"easing","params":{"name":6},"inputs":["duration3"]},"operation1":{"type":"operation","params":{"operation":1},"inputs":["position1"]},"operation2":{"type":"operation","params":{"operation":1},"inputs":["propertyValue3"]},"position1":{"type":"position","params":{"offset":0.05},"inputs":["propertyValue1"]},"position2":{"type":"position","inputs":["propertyValue2"]},"position3":{"type":"position","params":{"offset":0.05},"inputs":["propertyValue3"]},"position4":{"type":"position","inputs":["propertyValue4"]},"propertyName1":{"type":"propertyName","params":{"name":"rotation.x"},"inputs":["target1"]},"propertyName2":{"type":"propertyName","params":{"name":"rotation.x"},"inputs":["target2"]},"propertyValue1":{"type":"propertyValue","params":{"size":1,"value1":"$PI"},"inputs":["propertyName1"]},"propertyValue2":{"type":"propertyValue","params":{"size":1},"inputs":["propertyName1"]},"propertyValue3":{"type":"propertyValue","params":{"size":1,"value1":"$PI"},"inputs":["propertyName2"]},"propertyValue4":{"type":"propertyValue","params":{"size":1},"inputs":["propertyName2"]},"switch1":{"type":"switch","params":{"input":1},"inputs":["easing3","easing2","easing4"]},"target1":{"type":"target","params":{"objectMask":"*mainBox*"},"inputs":["switch1"]},"target2":{"type":"target","params":{"objectMask":"*mainBox_-1"},"inputs":["switch1"]}}},"EVENTS":{"type":"eventsNetwork","nodes":{"animation2":{"type":"animation","params":{"animation":"../../ANIM/PLAY1","stopsPreviousAnim":false},"inputs":[{"index":0,"node":"setParam1","output":"output"}]},"audio1":{"type":"audio","params":{"audio":"../../../positionalAudio1/OUT","note":"`ch(\"../intersectData_NOTE/attributeValues\")`"},"inputs":[{"index":0,"node":"param4","output":"valueChanged"}]},"intersectData_ID":{"type":"intersectData","params":{"attributeValue1":-1},"inputs":[{"index":0,"node":"raycast1","output":"hit"},{"index":1,"node":"raycast1","output":"miss"}]},"intersectData_NOTE":{"type":"intersectData","params":{"attributeName":"note","attributeType":1,"attributeValue1":-1},"inputs":[{"index":0,"node":"raycast1","output":"hit"},{"index":1,"node":"raycast1","output":"miss"}]},"mouse1":{"type":"mouse","params":{"mousedown":false,"mouseup":false}},"nodeCook1":{"type":"nodeCook","params":{"mask":"/rotatingBoxes/transform1","registerOnlyFirstCooks":false}},"param4":{"type":"param","params":{"param":"../intersectData_ID/attributeValue1","float":-1}},"raycast1":{"type":"raycast","params":{"mouse":[0.8715203426124196,-0.9656769390581716],"objectMask":"*mainBox*","traverseChildren":false,"position":[-5.394395355515165,4.248429965108464,4.7225804511378],"geoAttributeValue1":8},"inputs":[null,null,{"index":2,"node":"nodeCook1","output":"all"}]},"scene1":{"type":"scene"},"setParam1":{"type":"setParam","params":{"param":"/musicBoxes/ANIM/target2/objectMask","type":6,"string":"*mainBox_`ch(\"../intersectData_ID/attributeValue1\")`"},"inputs":[{"index":0,"node":"param4","output":"valueChanged"}]},"viewer1":{"type":"viewer","inputs":[{"index":0,"node":"raycast1","output":"hit"},{"index":1,"node":"raycast1","output":"miss"}]}}},"MAT":{"type":"materialsNetwork","nodes":{"meshStandard1":{"type":"meshStandard","params":{"useVertexColors":true,"useEnvMap":true,"envMap":"../../../COP/envMap","envMapIntensity":1.8,"metalness":0.16,"roughness":0.4,"useFog":true}}}},"actor1":{"type":"actor","nodes":{"add1":{"type":"add","params":{"add0":{"type":"float","default_value":0,"options":{"spare":true,"editable":false}},"add1":{"type":"float","default_value":0,"options":{"spare":true,"editable":true},"raw_input":1}},"inputs":[{"index":0,"node":"getObjectAttribute1","output":"val"}],"connection_points":{"in":[{"name":"add0","type":"float","isArray":false},{"name":"add1","type":"float","isArray":false}],"out":[{"name":"sum","type":"float","isArray":false}]}},"floatToVec3_1":{"type":"floatToVec3","params":{"x":{"overriden_options":{}},"y":{"overriden_options":{}},"z":{"overriden_options":{}}},"inputs":[{"index":0,"node":"mult1","output":"product"}]},"getObjectAttribute1":{"type":"getObjectAttribute","params":{"attribName":"rotationsCount"},"connection_points":{"in":[{"name":"Object3D","type":"Object3D","isArray":false}],"out":[{"name":"val","type":"float","isArray":false}]}},"getObjectAttribute2":{"type":"getObjectAttribute","params":{"attribName":"note","type":4},"connection_points":{"in":[{"name":"Object3D","type":"Object3D","isArray":false}],"out":[{"name":"val","type":"string","isArray":false}]}},"mult1":{"type":"mult","params":{"mult0":{"type":"float","default_value":1,"options":{"spare":true,"editable":false}},"mult1":{"type":"float","default_value":1,"options":{"spare":true,"editable":true},"raw_input":"$PI*0.5"}},"inputs":[{"index":0,"node":"getObjectAttribute1","output":"val"}],"connection_points":{"in":[{"name":"mult0","type":"float","isArray":false},{"name":"mult1","type":"float","isArray":false}],"out":[{"name":"product","type":"float","isArray":false}]}},"onEventObjectHovered1":{"type":"onObjectHover"},"onEventTick1":{"type":"onTick"},"playInstrumentNote1":{"type":"playInstrumentNote","params":{"node":"../../../positionalAudio1/OUT","note":{"overriden_options":{}},"duration":{"overriden_options":{}}},"maxInputsCount":4,"inputs":[{"index":0,"node":"triggerFilter1","output":"trigger"},null,{"index":2,"node":"getObjectAttribute2","output":"val"}]},"setObjectRotation1":{"type":"setObjectRotation","params":{"rotation":{"overriden_options":{}},"lerp":{"raw_input":0.14,"overriden_options":{}},"updateMatrix":{"overriden_options":{}}},"maxInputsCount":5,"inputs":[{"index":0,"node":"onEventTick1","output":"trigger"},null,{"index":2,"node":"floatToVec3_1","output":"vec3"}]},"triggerFilter1":{"type":"triggerFilter","params":{"condition":{"overriden_options":{}}},"maxInputsCount":2,"inputs":[{"index":0,"node":"onEventObjectHovered1","output":"trigger"},{"index":1,"node":"onEventObjectHovered1","output":"hovered"}]},"setObjectAttribute2":{"type":"setObjectAttribute","params":{"trigger":{"overriden_options":{}},"attribName":"rotationsCount","lerp":{"type":"float","default_value":1,"options":{"spare":true,"editable":true}},"val":{"type":"float","default_value":0,"options":{"spare":true,"editable":false}}},"maxInputsCount":4,"inputs":[{"index":0,"node":"triggerFilter1","output":"trigger"},null,null,{"index":3,"node":"add1","output":"sum"}],"connection_points":{"in":[{"name":"trigger","type":"trigger","isArray":false},{"name":"Object3D","type":"Object3D","isArray":false},{"name":"lerp","type":"float","isArray":false},{"name":"val","type":"float","isArray":false}],"out":[]}}},"inputs":["attribCreate5"],"flags":{"display":true}},"attribCreate1":{"type":"attribCreate","params":{"name":"scale","size":3,"value3":[1,"@height",1]},"inputs":["attribRemap1"]},"attribCreate2":{"type":"attribCreate","params":{"name":"height","value1":"@ptnum / (pointsCount(0)-1)"},"inputs":["transform2"]},"attribCreate3":{"type":"attribCreate","params":{"class":1,"name":"id","value1":"@ptnum"},"inputs":["attribPromote1"]},"attribCreate4":{"type":"attribCreate","params":{"class":1,"name":"id2","value1":"@id*2"},"inputs":["attribCreate3"]},"attribCreate5":{"type":"attribCreate","params":{"class":1,"name":"rotationsCount"},"inputs":["transform1"]},"attribPromote1":{"type":"attribPromote","params":{"classFrom":1,"classTo":0,"name":"color"},"inputs":["copy1"]},"attribRemap1":{"type":"attribRemap","params":{"name":"height","ramp":{"interpolation":"cubic","points":[{"position":0,"value":0.13749999999999996},{"position":0.1974589730015882,"value":0.4888671874999999},{"position":0.48205399682371625,"value":0.8013671875},{"position":0.7993399339933993,"value":0.43886718750000003},{"position":1,"value":1}]}},"inputs":["attribCreate2"]},"audioNotes1":{"type":"audioNotes","params":{"startOctave":3},"inputs":["objectProperties1"]},"copy1":{"type":"copy","params":{"copyAttributes":true,"attributesToCopy":"color"},"inputs":["material1","palette2"]},"line1":{"type":"line","params":{"length":20,"pointsCount":"(ch(\"length\")+1)/0.8","direction":[1,0,0]}},"material1":{"type":"material","params":{"material":"../MAT/meshStandard1"},"inputs":["roundedBox1"]},"objectProperties1":{"type":"objectProperties","params":{"tname":true,"name":"mainBox_`@id`"},"inputs":["attribCreate3"]},"palette2":{"type":"palette","params":{"colorsCount":4,"color1":{"raw_input":[0.8274509803921568,0.4117647058823529,0.24313725490196078],"overriden_options":{"0":"c","1":"o","2":"n","3":"v","4":"e","5":"r","6":"s","7":"i","8":"o","9":"n"}},"color2":{"raw_input":[0.5019607843137255,0.20784313725490197,0.1568627450980392],"overriden_options":{"0":"c","1":"o","2":"n","3":"v","4":"e","5":"r","6":"s","7":"i","8":"o","9":"n"}},"color3":{"raw_input":[0.9450980392156862,0.6941176470588235,0.33725490196078434],"overriden_options":{"0":"c","1":"o","2":"n","3":"v","4":"e","5":"r","6":"s","7":"i","8":"o","9":"n"}},"color4":{"raw_input":[0.5647058823529412,0.6549019607843137,0.596078431372549],"overriden_options":{"0":"c","1":"o","2":"n","3":"v","4":"e","5":"r","6":"s","7":"i","8":"o","9":"n"}},"color5":[0.2549019607843137,0.5529411764705883,0.803921568627451]},"inputs":["attribCreate1"]},"roundedBox1":{"type":"roundedBox","params":{"size":0.77,"sizes":[1,8,1],"divisions":6,"bevel":0.16}},"transform1":{"type":"transform","params":{"applyOn":1,"objectMode":1},"inputs":["audioNotes1"]},"transform2":{"type":"transform","params":{"t":["-$CEX",5.212417308354685,0]},"inputs":["line1"]}},"params":{"r":[0,38.15006823740499,0]},"flags":{"display":true}},"rotatingSpheres":{"type":"geo","nodes":{"MAT":{"type":"materialsNetwork","nodes":{"meshPhysicalBuilder1":{"type":"meshPhysicalBuilder","nodes":{"abs1":{"type":"abs","params":{"in":{"type":"float","default_value":0,"options":{"spare":true,"editable":false}}},"inputs":[{"index":0,"node":"noise1","output":"noise"}],"connection_points":{"in":[{"name":"in","type":"float"}],"out":[{"name":"val","type":"float"}]}},"add1":{"type":"add","params":{"add0":{"type":"float","default_value":0,"options":{"spare":true,"editable":false}},"add1":{"type":"float","default_value":0,"options":{"spare":true,"editable":false}},"add2":{"type":"float","default_value":0,"options":{"spare":true,"editable":true}}},"maxInputsCount":3,"inputs":[{"index":0,"node":"constant1","output":"val"},{"index":1,"node":"noise1","output":"noise"}],"connection_points":{"in":[{"name":"add0","type":"float"},{"name":"add1","type":"float"},{"name":"add2","type":"float"}],"out":[{"name":"sum","type":"float"}]}},"attribute1":{"type":"attribute","params":{"name":"instancePosition","type":2},"connection_points":{"in":[],"out":[{"name":"val","type":"vec3"}]}},"attribute2":{"type":"attribute","params":{"name":"id"},"connection_points":{"in":[],"out":[{"name":"val","type":"float"}]}},"constant1":{"type":"constant","params":{"float":1},"connection_points":{"in":[],"out":[{"name":"val","type":"float"}]}},"floatToVec2_1":{"type":"floatToVec2","params":{"x":{"overriden_options":{}},"y":{"overriden_options":{}}},"inputs":[{"index":0,"node":"round1","output":"val"}]},"globals1":{"type":"globals"},"instanceTransform1":{"type":"instanceTransform","params":{"position":{"overriden_options":{}},"normal":{"overriden_options":{}},"instancePosition":{"overriden_options":{}},"instanceOrientation":{"overriden_options":{}},"instanceScale":{"overriden_options":{}}},"inputs":[null,null,{"index":2,"node":"mult1","output":"product"}]},"length1":{"type":"length","params":{"x":{"type":"vector3","default_value":[0,0,0],"options":{"spare":true,"editable":false}}},"inputs":[{"index":0,"node":"attribute1","output":"val"}],"connection_points":{"in":[{"name":"x","type":"vec3"}],"out":[{"name":"val","type":"float"}]}},"mult1":{"type":"mult","params":{"mult0":{"type":"float","default_value":1,"options":{"spare":true,"editable":false}},"mult1":{"type":"vector3","default_value":[1,1,1],"options":{"spare":true,"editable":false}}},"inputs":[{"index":0,"node":"length1","output":"val"},{"index":1,"node":"rotate1","output":"val"}],"connection_points":{"in":[{"name":"mult0","type":"float"},{"name":"mult1","type":"vec3"}],"out":[{"name":"product","type":"vec3"}]}},"multAdd1":{"type":"multAdd","params":{"value":{"type":"float","default_value":0,"options":{"spare":true,"editable":false}},"preAdd":{"type":"float","default_value":0,"options":{"spare":true,"editable":true}},"mult":{"type":"float","default_value":1,"options":{"spare":true,"editable":true},"raw_input":0.51},"postAdd":{"type":"float","default_value":0,"options":{"spare":true,"editable":true}}},"inputs":[{"index":0,"node":"globals1","output":"time"}],"connection_points":{"in":[{"name":"value","type":"float"},{"name":"preAdd","type":"float"},{"name":"mult","type":"float"},{"name":"postAdd","type":"float"}],"out":[{"name":"val","type":"float"}]}},"noise1":{"type":"noise","params":{"outputType":1,"amp":{"type":"float","default_value":1,"options":{"spare":true,"editable":true},"raw_input":0.45},"position":{"type":"vector3","default_value":[0,0,0],"options":{"spare":true,"editable":false}},"freq":{"type":"vector3","default_value":[1,1,1],"options":{"spare":true,"editable":true},"raw_input":[100,100,100]},"offset":{"type":"vector3","default_value":[0,0,0],"options":{"spare":true,"editable":true}}},"maxInputsCount":4,"inputs":[null,{"index":1,"node":"globals1","output":"position"}],"connection_points":{"in":[{"name":"amp","type":"float"},{"name":"position","type":"vec3"},{"name":"freq","type":"vec3"},{"name":"offset","type":"vec3"}],"out":[{"name":"noise","type":"float"}]}},"normalize1":{"type":"normalize","params":{"in":{"type":"vector3","default_value":[0,0,0],"options":{"spare":true,"editable":false}}},"inputs":[{"index":0,"node":"attribute1","output":"val"}],"connection_points":{"in":[{"name":"in","type":"vec3"}],"out":[{"name":"normalized","type":"vec3"}]}},"output1":{"type":"output","inputs":[{"index":0,"node":"instanceTransform1","output":"position"},{"index":1,"node":"instanceTransform1","output":"normal"},null,null,null,null,{"index":6,"node":"random1","output":"rand"},null,null,null,{"index":10,"node":"add1","output":"sum"}]},"random1":{"type":"random","params":{"seed":{"overriden_options":{}}},"inputs":[{"index":0,"node":"floatToVec2_1","output":"vec2"}]},"rotate1":{"type":"rotate","params":{"vector":{"type":"vector3","default_value":[0,0,1],"options":{"spare":true,"editable":false}},"axis":{"type":"vector3","default_value":[0,1,0],"options":{"spare":true,"editable":true},"raw_input":[0,0,1]},"angle":{"type":"float","default_value":0,"options":{"spare":true,"editable":false}}},"maxInputsCount":3,"inputs":[{"index":0,"node":"normalize1","output":"normalized"},null,{"index":2,"node":"multAdd1","output":"val"}],"connection_points":{"in":[{"name":"vector","type":"vec3"},{"name":"axis","type":"vec3"},{"name":"angle","type":"float"}],"out":[{"name":"val","type":"vec3"}]}},"round1":{"type":"round","params":{"in":{"type":"float","default_value":0,"options":{"spare":true,"editable":false}}},"inputs":[{"index":0,"node":"attribute2","output":"val"}],"connection_points":{"in":[{"name":"in","type":"float"}],"out":[{"name":"val","type":"float"}]}}},"params":{"useEnvMap":true,"envMap":"../../../COP/envMap","envMapIntensity":1.5,"metalness":0.06,"clearcoat":1,"clearcoatRoughness":0.01,"transmission":1,"ior":1.679983,"thickness":0.7,"attenuationDistance":2.7,"attenuationColor":[0.023529411764705882,0.07450980392156863,0.17647058823529413]},"persisted_config":{"material":{"metadata":{"version":4.5,"type":"Material","generator":"Material.toJSON"},"uuid":"/rotatingSpheres/MAT/meshPhysicalBuilder1-main","type":"MeshPhysicalMaterial","name":"/rotatingSpheres/MAT/meshPhysicalBuilder1","color":16777215,"roughness":1,"metalness":0.06,"sheen":0,"sheenColor":0,"sheenRoughness":1,"emissive":0,"specularIntensity":1,"specularColor":16777215,"clearcoat":1,"clearcoatRoughness":0.01,"iridescence":0,"iridescenceIOR":1.3,"iridescenceThicknessRange":[100,400],"envMapIntensity":1.5,"reflectivity":0.6343165236495905,"transmission":1,"thickness":0.7,"attenuationDistance":2.7,"attenuationColor":398125,"depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680,"fog":false},"onBeforeCompileDataJSONWithoutShaders":{"paramConfigs":[],"timeDependent":true,"resolutionDependent":false},"customMaterials":{"customDepthMaterial":{"material":{"metadata":{"version":4.5,"type":"Material","generator":"Material.toJSON"},"uuid":"/rotatingSpheres/MAT/meshPhysicalBuilder1-customDepthMaterial","type":"MeshDepthMaterial","name":"customDepthMaterial","depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680,"depthPacking":3201},"onBeforeCompileDataJSONWithoutShaders":{"paramConfigs":[],"timeDependent":true,"resolutionDependent":false}},"customDistanceMaterial":{"material":{"metadata":{"version":4.5,"type":"Material","generator":"Material.toJSON"},"uuid":"/rotatingSpheres/MAT/meshPhysicalBuilder1-customDistanceMaterial","type":"MeshDistanceMaterial","name":"customDistanceMaterial","depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680},"onBeforeCompileDataJSONWithoutShaders":{"paramConfigs":[],"timeDependent":true,"resolutionDependent":false}},"customDepthDOFMaterial":{"material":{"metadata":{"version":4.5,"type":"Material","generator":"Material.toJSON"},"uuid":"/rotatingSpheres/MAT/meshPhysicalBuilder1-customDepthDOFMaterial","type":"MeshDepthMaterial","name":"customDepthDOFMaterial","depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680,"depthPacking":3200},"onBeforeCompileDataJSONWithoutShaders":{"paramConfigs":[],"timeDependent":true,"resolutionDependent":false}}}}}}},"instance1":{"type":"instance","params":{"attributesToCopy":"instance* id","material":"../MAT/meshPhysicalBuilder1"},"inputs":["sphere1","scatter1"],"flags":{"display":true}},"scatter1":{"type":"scatter","params":{"pointsCount":10,"seed":13},"inputs":["tube1"]},"sphere1":{"type":"sphere"},"transform1":{"type":"transform"},"tube1":{"type":"tube","params":{"radiusTop":4.8,"radiusBottom":4.5,"height":22.900000000000002}}},"inputs":["null2"],"flags":{"display":true}},"perspectiveCamera_MAIN":{"type":"perspectiveCamera","nodes":{"events1":{"type":"eventsNetwork","nodes":{"cameraOrbitControls1":{"type":"cameraOrbitControls","params":{"allowPan":false,"minDistance":16,"maxDistance":22,"limitAzimuthAngle":true,"azimuthAngleRange":["-0.4*$PI","0.4*$PI"],"polarAngleRange":[0,"$PI*0.5"],"target":[-1.7511417564003886,4.8056149140646625,2.228021894132138]}}}},"renderersNetwork1":{"type":"renderersNetwork","nodes":{"WebGLRenderer1":{"type":"WebGLRenderer","params":{"alpha":false,"toneMapping":0}}}}},"params":{"t":[4.645050942978928,11.201242947142884,18.551025336113412],"r":[-21.396083605161095,20.044262726375518,7.648697907782715],"controls":"./events1/cameraOrbitControls1","setRenderer":true,"renderer":"renderersNetwork1/WebGLRenderer1"},"flags":{"display":true}},"perspectiveCamera_DEBUG":{"type":"perspectiveCamera","nodes":{"events1":{"type":"eventsNetwork","nodes":{"cameraOrbitControls2":{"type":"cameraOrbitControls","params":{"target":[-0.35568100073133685,3.9096117890283693,-1.531413882739077]}}}}},"params":{"t":[1.0049354542845284,9.022002997743003,18.177143989703644],"r":[-14.541987088239498,3.8231157746708253,0.990879998730258],"controls":"events1/cameraOrbitControls2","setRenderer":true,"renderer":"../perspectiveCamera_MAIN/renderersNetwork1/WebGLRenderer1"},"flags":{"display":true}},"null2":{"type":"null","params":{"t":[0,5.312613522707743,0],"r":[0,-49.365682806890725,0]},"flags":{"display":false}}},"params":{"mainCameraPath":"/perspectiveCamera_MAIN","useFog":1,"fogColor":[0,0,0],"fogDensity":0.02,"displayAudioIcon":1}},"ui":{"nodes":{"hemisphereLight1":{"pos":[100,350]},"spotLight1":{"pos":[250,450]},"COP":{"pos":[-350,350],"nodes":{"envMap":{"pos":[50,200]},"imageEnv":{"pos":[50,100]},"imageUv":{"pos":[-100,100]}}},"set":{"pos":[-350,-250],"nodes":{"MAT":{"pos":[-50,350],"nodes":{"meshStandard1":{"pos":[0,200]}}},"circle1":{"pos":[250,-650]},"material1":{"pos":[250,450]},"skin1":{"pos":[250,200]},"transform1":{"pos":[400,0]},"transform2":{"pos":[250,-550]},"transform3":{"pos":[250,-450]},"transform4":{"pos":[250,-300]},"transform5":{"pos":[250,-200]},"transform6":{"pos":[150,0]},"transform7":{"pos":[250,550]},"transform8":{"pos":[250,650]},"transform9":{"pos":[250,300]}}},"polarTransform1":{"pos":[250,250]},"gridHelper":{"pos":[-350,-350],"nodes":{"plane1":{"pos":[50,-150]},"planeHelper1":{"pos":[200,-100]}}},"spotLight2":{"pos":[450,450]},"polarTransform2":{"pos":[450,250]},"null1":{"pos":[250,150]},"contactShadow1":{"pos":[200,-50]},"positionalAudio1":{"pos":[-350,-50],"nodes":{"OUT":{"pos":[100,150]},"Synth1":{"pos":[300,-400]},"chorus1":{"pos":[350,-200]},"chorus2":{"pos":[500,-100]},"envelope1":{"pos":[0,-650]},"monoSynth1":{"pos":[0,-450]},"pitchShift1":{"pos":[500,-200]},"playInstrument1":{"pos":[100,300]},"polySynth1":{"pos":[550,-300]},"reverb1":{"pos":[-50,-150]},"reverb2":{"pos":[150,-200]},"switch1":{"pos":[-250,-300]},"switch2":{"pos":[50,50]},"volume1":{"pos":[-50,-50]}}},"audioListener1":{"pos":[-500,450]},"musicBoxes":{"pos":[-350,-150],"nodes":{"ANIM":{"pos":[-400,300],"nodes":{"PLAY":{"pos":[0,900]},"PLAY1":{"pos":[550,900]},"RESET":{"pos":[-300,700]},"RESET1":{"pos":[250,700]},"duration1":{"pos":[450,-200]},"duration2":{"pos":[600,-150]},"duration3":{"pos":[800,-200]},"duration5":{"pos":[0,0]},"easing1":{"pos":[0,100]},"easing2":{"pos":[600,-50]},"easing3":{"pos":[450,-50]},"easing4":{"pos":[800,-50]},"operation1":{"pos":[0,700]},"operation2":{"pos":[550,700]},"position1":{"pos":[0,600]},"position2":{"pos":[-300,600]},"position3":{"pos":[650,600]},"position4":{"pos":[250,600]},"propertyName1":{"pos":[0,400]},"propertyName2":{"pos":[550,400]},"propertyValue1":{"pos":[0,500]},"propertyValue2":{"pos":[-300,500]},"propertyValue3":{"pos":[550,500]},"propertyValue4":{"pos":[250,500]},"switch1":{"pos":[550,150]},"target1":{"pos":[0,300]},"target2":{"pos":[550,300]}}},"EVENTS":{"pos":[-400,400],"nodes":{"animation2":{"pos":[150,500]},"audio1":{"pos":[150,700]},"intersectData_ID":{"pos":[-150,150]},"intersectData_NOTE":{"pos":[-150,250]},"mouse1":{"pos":[-600,350]},"nodeCook1":{"pos":[-450,550]},"param4":{"pos":[-150,550]},"raycast1":{"pos":[-300,400]},"scene1":{"pos":[-450,300]},"setParam1":{"pos":[0,550]},"viewer1":{"pos":[-50,350]}}},"MAT":{"pos":[-400,200],"nodes":{"meshStandard1":{"pos":[-300,500]}}},"actor1":{"pos":[-100,1400],"nodes":{"add1":{"pos":[200,-200]},"floatToVec3_1":{"pos":[300,100]},"getObjectAttribute1":{"pos":[-50,-200]},"getObjectAttribute2":{"pos":[200,-550]},"mult1":{"pos":[200,100]},"onEventObjectHovered1":{"pos":[0,-400]},"onEventTick1":{"pos":[300,-50]},"playInstrumentNote1":{"pos":[450,-500]},"setObjectRotation1":{"pos":[550,0],"comment":"try change change the lerp parameter. The smaller the value, the slower the objects will rotate when hovering the mouse over them (but make sure to play the scene first)"},"triggerFilter1":{"pos":[200,-400]},"setObjectAttribute2":{"pos":[450,-350]}}},"attribCreate1":{"pos":[100,200]},"attribCreate2":{"pos":[100,-150]},"attribCreate3":{"pos":[-100,750]},"attribCreate4":{"pos":[50,850]},"attribCreate5":{"pos":[-100,1250]},"attribPromote1":{"pos":[-100,600]},"attribRemap1":{"pos":[100,50]},"audioNotes1":{"pos":[-100,1000]},"copy1":{"pos":[-100,500]},"line1":{"pos":[100,-400]},"material1":{"pos":[-100,300]},"objectProperties1":{"pos":[-100,900]},"palette2":{"pos":[100,300]},"roundedBox1":{"pos":[-100,-200]},"transform1":{"pos":[-100,1150]},"transform2":{"pos":[100,-300]}}},"rotatingSpheres":{"pos":[-150,-250],"nodes":{"MAT":{"pos":[-350,400],"nodes":{"meshPhysicalBuilder1":{"pos":[-150,250],"nodes":{"abs1":{"pos":[0,300]},"add1":{"pos":[100,200]},"attribute1":{"pos":[-500,-100]},"attribute2":{"pos":[-150,500]},"constant1":{"pos":[-50,200]},"floatToVec2_1":{"pos":[50,500]},"globals1":{"pos":[-600,100]},"instanceTransform1":{"pos":[50,0]},"length1":{"pos":[-300,-100]},"mult1":{"pos":[-50,-100]},"multAdd1":{"pos":[-450,300]},"noise1":{"pos":[-100,300]},"normalize1":{"pos":[-350,50]},"output1":{"pos":[300,0]},"random1":{"pos":[150,500]},"rotate1":{"pos":[-200,50]},"round1":{"pos":[-50,500]}}}}},"instance1":{"pos":[-50,450]},"scatter1":{"pos":[50,250]},"sphere1":{"pos":[-150,250]},"transform1":{"pos":[-150,0]},"tube1":{"pos":[50,-100]}}},"perspectiveCamera_MAIN":{"pos":[-500,250],"nodes":{"events1":{"pos":[-200,50],"nodes":{"cameraOrbitControls1":{"pos":[150,50]}}},"renderersNetwork1":{"pos":[-200,150],"nodes":{"WebGLRenderer1":{"pos":[-200,150]}}}}},"perspectiveCamera_DEBUG":{"pos":[-500,100],"nodes":{"events1":{"pos":[-200,50],"nodes":{"cameraOrbitControls2":{"pos":[-100,200]}}}}},"null2":{"pos":[-150,-350]}}},"shaders":{"/rotatingSpheres/MAT/meshPhysicalBuilder1":{"vertex":"#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n\tvarying vec3 vWorldPosition;\n#endif\n#include <common>\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/rotate1\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n\n\n\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nuniform float time;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nvarying vec3 v_POLY_globals1_position;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nvarying float v_POLY_attribute_id;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute1\nattribute vec3 instancePosition;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nattribute float id;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/instanceTransform1\nattribute vec4 instanceOrientation;\nattribute vec3 instanceScale;\n\n\n\n\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\n\n\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute1\n\tvec3 v_POLY_attribute1_val = instancePosition;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\n\tv_POLY_globals1_position = vec3(position);\n\tfloat v_POLY_globals1_time = time;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\n\tv_POLY_attribute_id = float(id);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/length1\n\tfloat v_POLY_length1_val = length(v_POLY_attribute1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/normalize1\n\tvec3 v_POLY_normalize1_normalized = normalize(v_POLY_attribute1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/multAdd1\n\tfloat v_POLY_multAdd1_val = (0.51*(v_POLY_globals1_time + 0.0)) + 0.0;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/rotate1\n\tvec3 v_POLY_rotate1_val = rotateWithAxisAngle(v_POLY_normalize1_normalized, vec3(0.0, 0.0, 1.0), v_POLY_multAdd1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/mult1\n\tvec3 v_POLY_mult1_product = (v_POLY_length1_val * v_POLY_rotate1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/instanceTransform1\n\tvec3 v_POLY_instanceTransform1_position = vec3(position);\n\tv_POLY_instanceTransform1_position *= instanceScale;\n\tv_POLY_instanceTransform1_position = rotateWithQuat( v_POLY_instanceTransform1_position, instanceOrientation );\n\tv_POLY_instanceTransform1_position += v_POLY_mult1_product;\n\tvec3 v_POLY_instanceTransform1_normal = vec3(normal);\n\tv_POLY_instanceTransform1_normal = rotateWithQuat( v_POLY_instanceTransform1_normal, instanceOrientation );\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/output1\n\tvec3 transformed = v_POLY_instanceTransform1_position;\n\tvec3 objectNormal = v_POLY_instanceTransform1_normal;\n\t#ifdef USE_TANGENT\n\t\tvec3 objectTangent = vec3( tangent.xyz );\n\t#endif\n\n\n\n\t#include <morphcolor_vertex>\n// removed:\n//\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n// removed:\n//\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n#ifdef USE_TRANSMISSION\n\tvWorldPosition = worldPosition.xyz;\n#endif\n}","fragment":"#define STANDARD\n#ifdef PHYSICAL\n\t#define IOR\n\t#define SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n\tuniform float ior;\n#endif\n#ifdef SPECULAR\n\tuniform float specularIntensity;\n\tuniform vec3 specularColor;\n\t#ifdef USE_SPECULARINTENSITYMAP\n\t\tuniform sampler2D specularIntensityMap;\n\t#endif\n\t#ifdef USE_SPECULARCOLORMAP\n\t\tuniform sampler2D specularColorMap;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_IRIDESCENCE\n\tuniform float iridescence;\n\tuniform float iridescenceIOR;\n\tuniform float iridescenceThicknessMinimum;\n\tuniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheenColor;\n\tuniform float sheenRoughness;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tuniform sampler2D sheenColorMap;\n\t#endif\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tuniform sampler2D sheenRoughnessMap;\n\t#endif\n#endif\nvarying vec3 vViewPosition;\n#include <common>\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/noise1\n// Modulo 289 without a division (only multiplications)\nfloat mod289(float x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec2 mod289(vec2 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec3 mod289(vec3 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec4 mod289(vec4 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n// Modulo 7 without a division\nvec3 mod7(vec3 x) {\n return x - floor(x * (1.0 / 7.0)) * 7.0;\n}\n\n// Permutation polynomial: (34x^2 + x) mod 289\nfloat permute(float x) {\n return mod289(((x*34.0)+1.0)*x);\n}\nvec3 permute(vec3 x) {\n return mod289((34.0 * x + 1.0) * x);\n}\nvec4 permute(vec4 x) {\n return mod289(((x*34.0)+1.0)*x);\n}\n\nfloat taylorInvSqrt(float r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\nvec4 taylorInvSqrt(vec4 r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\n\nvec2 fade(vec2 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\nvec3 fade(vec3 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\nvec4 fade(vec4 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\n//\n// Description : Array and textureless GLSL 2D/3D/4D simplex \n// noise functions.\n// Author : Ian McEwan, Ashima Arts.\n// Maintainer : stegu\n// Lastmod : 20110822 (ijm)\n// License : Copyright (C) 2011 Ashima Arts. All rights reserved.\n// Distributed under the MIT License. See LICENSE file.\n// https://github.com/ashima/webgl-noise\n// https://github.com/stegu/webgl-noise\n// \n\n\n\nfloat snoise(vec3 v)\n { \n const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\n// First corner\n vec3 i = floor(v + dot(v, C.yyy) );\n vec3 x0 = v - i + dot(i, C.xxx) ;\n\n// Other corners\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min( g.xyz, l.zxy );\n vec3 i2 = max( g.xyz, l.zxy );\n\n // x0 = x0 - 0.0 + 0.0 * C.xxx;\n // x1 = x0 - i1 + 1.0 * C.xxx;\n // x2 = x0 - i2 + 2.0 * C.xxx;\n // x3 = x0 - 1.0 + 3.0 * C.xxx;\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y\n vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y\n\n// Permutations\n i = mod289(i); \n vec4 p = permute( permute( permute( \n i.z + vec4(0.0, i1.z, i2.z, 1.0 ))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) \n + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));\n\n// Gradients: 7x7 points over a square, mapped onto an octahedron.\n// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)\n float n_ = 0.142857142857; // 1.0/7.0\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)\n\n vec4 x = x_ *ns.x + ns.yyyy;\n vec4 y = y_ *ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n\n vec4 b0 = vec4( x.xy, y.xy );\n vec4 b1 = vec4( x.zw, y.zw );\n\n //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;\n //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;\n vec4 s0 = floor(b0)*2.0 + 1.0;\n vec4 s1 = floor(b1)*2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;\n\n vec3 p0 = vec3(a0.xy,h.x);\n vec3 p1 = vec3(a0.zw,h.y);\n vec3 p2 = vec3(a1.xy,h.z);\n vec3 p3 = vec3(a1.zw,h.w);\n\n//Normalise gradients\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n// Mix final noise value\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), \n dot(p2,x2), dot(p3,x3) ) );\n }\n\n\nfloat fbm_snoise_rotatingSpheres_MAT_meshPhysicalBuilder1_noise1(in vec3 st) {\n\tfloat value = 0.0;\n\tfloat amplitude = 1.0;\n\tfor (int i = 0; i < 3; i++) {\n\t\tvalue += amplitude * snoise(st);\n\t\tst *= 2.0;\n\t\tamplitude *= 0.5;\n\t}\n\treturn value;\n}\n\n\n\n\n\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nuniform float time;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nvarying vec3 v_POLY_globals1_position;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nvarying float v_POLY_attribute_id;\n\n\n\n\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <bsdfs>\n#include <iridescence_fragment>\n#include <cube_uv_reflection_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_physical_pars_fragment>\n#include <fog_pars_fragment>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_physical_pars_fragment>\n#include <transmission_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <clearcoat_pars_fragment>\n#include <iridescence_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nstruct SSSModel {\n\tbool isActive;\n\tvec3 color;\n\tfloat thickness;\n\tfloat power;\n\tfloat scale;\n\tfloat distortion;\n\tfloat ambient;\n\tfloat attenuation;\n};\n\nvoid RE_Direct_Scattering(\n\tconst in IncidentLight directLight,\n\tconst in GeometricContext geometry,\n\tconst in SSSModel sssModel,\n\tinout ReflectedLight reflectedLight\n\t){\n\tvec3 scatteringHalf = normalize(directLight.direction + (geometry.normal * sssModel.distortion));\n\tfloat scatteringDot = pow(saturate(dot(geometry.viewDir, -scatteringHalf)), sssModel.power) * sssModel.scale;\n\tvec3 scatteringIllu = (scatteringDot + sssModel.ambient) * (sssModel.color * (1.0-sssModel.thickness));\n\treflectedLight.directDiffuse += scatteringIllu * sssModel.attenuation * directLight.color;\n}\n\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\n\n\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\n\tfloat v_POLY_globals1_time = time;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\n\tfloat v_POLY_attribute2_val = v_POLY_attribute_id;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/constant1\n\tfloat v_POLY_constant1_val = 1.0;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/noise1\n\tfloat v_POLY_noise1_noise = 0.45*fbm_snoise_rotatingSpheres_MAT_meshPhysicalBuilder1_noise1((v_POLY_globals1_position*vec3(100.0, 100.0, 100.0))+vec3(0.0, 0.0, 0.0));\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/round1\n\tfloat v_POLY_round1_val = sign(v_POLY_attribute2_val)*floor(abs(v_POLY_attribute2_val)+0.5);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/add1\n\tfloat v_POLY_add1_sum = (v_POLY_constant1_val + v_POLY_noise1_noise + 0.0);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_round1_val, 0.0);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/random1\n\tfloat v_POLY_random1_rand = rand(v_POLY_floatToVec2_1_vec2);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/output1\n\tfloat POLY_metalness = 1.0;\n\tfloat POLY_roughness = v_POLY_random1_rand;\n\tvec3 POLY_emissive = vec3(1.0, 1.0, 1.0);\n\tSSSModel POLY_SSSModel = SSSModel(/*isActive*/false,/*color*/vec3(1.0, 1.0, 1.0), /*thickness*/0.1, /*power*/2.0, /*scale*/16.0, /*distortion*/0.1,/*ambient*/0.4,/*attenuation*/0.8 );\n\tfloat POLY_transmission = 1.0;\n\tfloat POLY_thickness = v_POLY_add1_sum;\n\n\n\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive * POLY_emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\tfloat roughnessFactor = roughness * POLY_roughness;\n\n#ifdef USE_ROUGHNESSMAP\n\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\n\t// reads channel G, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n\troughnessFactor *= texelRoughness.g;\n\n#endif\n\n\tfloat metalnessFactor = metalness * POLY_metalness;\n\n#ifdef USE_METALNESSMAP\n\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\n\t// reads channel B, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n\tmetalnessFactor *= texelMetalness.b;\n\n#endif\n\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <clearcoat_normal_fragment_begin>\n\t#include <clearcoat_normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_fragment_begin>\nif(POLY_SSSModel.isActive){\n\tRE_Direct_Scattering(directLight, geometry, POLY_SSSModel, reflectedLight);\n}\n\n\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n\tvec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\t\n#ifdef USE_TRANSMISSION\n\n\tmaterial.transmission = transmission;\n\tmaterial.transmissionAlpha = 1.0;\n\tmaterial.thickness = thickness;\n\tmaterial.attenuationDistance = attenuationDistance;\n\tmaterial.attenuationColor = attenuationColor;\n\n\t#ifdef USE_TRANSMISSIONMAP\n\n\t\tmaterial.transmission *= texture2D( transmissionMap, vUv ).r;\n\n\t#endif\n\n\t#ifdef USE_THICKNESSMAP\n\n\t\tmaterial.thickness *= texture2D( thicknessMap, vUv ).g;\n\n\t#endif\n\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\n\tvec4 transmission = getIBLVolumeRefraction(\n\t\tn, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, material.ior, material.thickness,\n\t\tmaterial.attenuationColor, material.attenuationDistance );\n\n\tmaterial.transmissionAlpha = mix( material.transmissionAlpha, transmission.a, material.transmission );\n\n\ttotalDiffuse = mix( totalDiffuse, transmission.rgb, material.transmission );\n\n#endif\n\n\tvec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n\t#ifdef USE_SHEEN\n\t\tfloat sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor );\n\t\toutgoingLight = outgoingLight * sheenEnergyComp + sheenSpecular;\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNVcc = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\tvec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n\t\toutgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + clearcoatSpecular * material.clearcoat;\n\t#endif\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}","customDepthMaterial.vertex":"#include <common>\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/rotate1\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n\n\n\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nuniform float time;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nvarying vec3 v_POLY_globals1_position;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nvarying float v_POLY_attribute_id;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute1\nattribute vec3 instancePosition;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nattribute float id;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/instanceTransform1\nattribute vec4 instanceOrientation;\nattribute vec3 instanceScale;\n\n\n\n\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n// removed:\n//\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n// removed:\n//\t#include <begin_vertex>\n\n\n\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute1\n\tvec3 v_POLY_attribute1_val = instancePosition;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\n\tv_POLY_globals1_position = vec3(position);\n\tfloat v_POLY_globals1_time = time;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\n\tv_POLY_attribute_id = float(id);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/length1\n\tfloat v_POLY_length1_val = length(v_POLY_attribute1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/normalize1\n\tvec3 v_POLY_normalize1_normalized = normalize(v_POLY_attribute1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/multAdd1\n\tfloat v_POLY_multAdd1_val = (0.51*(v_POLY_globals1_time + 0.0)) + 0.0;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/rotate1\n\tvec3 v_POLY_rotate1_val = rotateWithAxisAngle(v_POLY_normalize1_normalized, vec3(0.0, 0.0, 1.0), v_POLY_multAdd1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/mult1\n\tvec3 v_POLY_mult1_product = (v_POLY_length1_val * v_POLY_rotate1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/instanceTransform1\n\tvec3 v_POLY_instanceTransform1_position = vec3(position);\n\tv_POLY_instanceTransform1_position *= instanceScale;\n\tv_POLY_instanceTransform1_position = rotateWithQuat( v_POLY_instanceTransform1_position, instanceOrientation );\n\tv_POLY_instanceTransform1_position += v_POLY_mult1_product;\n\tvec3 v_POLY_instanceTransform1_normal = vec3(normal);\n\tv_POLY_instanceTransform1_normal = rotateWithQuat( v_POLY_instanceTransform1_normal, instanceOrientation );\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/output1\n\tvec3 transformed = v_POLY_instanceTransform1_position;\n\tvec3 objectNormal = v_POLY_instanceTransform1_normal;\n\t#ifdef USE_TANGENT\n\t\tvec3 objectTangent = vec3( tangent.xyz );\n\t#endif\n\n\n\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvHighPrecisionZW = gl_Position.zw;\n}","customDepthMaterial.fragment":"\n// INSERT DEFINES\n\n\n#if DEPTH_PACKING == 3200\n\n\tuniform float opacity;\n\n#endif\n\n#include <common>\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/noise1\n// Modulo 289 without a division (only multiplications)\nfloat mod289(float x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec2 mod289(vec2 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec3 mod289(vec3 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec4 mod289(vec4 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n// Modulo 7 without a division\nvec3 mod7(vec3 x) {\n return x - floor(x * (1.0 / 7.0)) * 7.0;\n}\n\n// Permutation polynomial: (34x^2 + x) mod 289\nfloat permute(float x) {\n return mod289(((x*34.0)+1.0)*x);\n}\nvec3 permute(vec3 x) {\n return mod289((34.0 * x + 1.0) * x);\n}\nvec4 permute(vec4 x) {\n return mod289(((x*34.0)+1.0)*x);\n}\n\nfloat taylorInvSqrt(float r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\nvec4 taylorInvSqrt(vec4 r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\n\nvec2 fade(vec2 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\nvec3 fade(vec3 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\nvec4 fade(vec4 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\n//\n// Description : Array and textureless GLSL 2D/3D/4D simplex \n// noise functions.\n// Author : Ian McEwan, Ashima Arts.\n// Maintainer : stegu\n// Lastmod : 20110822 (ijm)\n// License : Copyright (C) 2011 Ashima Arts. All rights reserved.\n// Distributed under the MIT License. See LICENSE file.\n// https://github.com/ashima/webgl-noise\n// https://github.com/stegu/webgl-noise\n// \n\n\n\nfloat snoise(vec3 v)\n { \n const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\n// First corner\n vec3 i = floor(v + dot(v, C.yyy) );\n vec3 x0 = v - i + dot(i, C.xxx) ;\n\n// Other corners\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min( g.xyz, l.zxy );\n vec3 i2 = max( g.xyz, l.zxy );\n\n // x0 = x0 - 0.0 + 0.0 * C.xxx;\n // x1 = x0 - i1 + 1.0 * C.xxx;\n // x2 = x0 - i2 + 2.0 * C.xxx;\n // x3 = x0 - 1.0 + 3.0 * C.xxx;\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y\n vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y\n\n// Permutations\n i = mod289(i); \n vec4 p = permute( permute( permute( \n i.z + vec4(0.0, i1.z, i2.z, 1.0 ))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) \n + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));\n\n// Gradients: 7x7 points over a square, mapped onto an octahedron.\n// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)\n float n_ = 0.142857142857; // 1.0/7.0\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)\n\n vec4 x = x_ *ns.x + ns.yyyy;\n vec4 y = y_ *ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n\n vec4 b0 = vec4( x.xy, y.xy );\n vec4 b1 = vec4( x.zw, y.zw );\n\n //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;\n //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;\n vec4 s0 = floor(b0)*2.0 + 1.0;\n vec4 s1 = floor(b1)*2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;\n\n vec3 p0 = vec3(a0.xy,h.x);\n vec3 p1 = vec3(a0.zw,h.y);\n vec3 p2 = vec3(a1.xy,h.z);\n vec3 p3 = vec3(a1.zw,h.w);\n\n//Normalise gradients\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n// Mix final noise value\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), \n dot(p2,x2), dot(p3,x3) ) );\n }\n\n\nfloat fbm_snoise_rotatingSpheres_MAT_meshPhysicalBuilder1_noise1(in vec3 st) {\n\tfloat value = 0.0;\n\tfloat amplitude = 1.0;\n\tfor (int i = 0; i < 3; i++) {\n\t\tvalue += amplitude * snoise(st);\n\t\tst *= 2.0;\n\t\tamplitude *= 0.5;\n\t}\n\treturn value;\n}\n\n\n\n\n\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nuniform float time;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nvarying vec3 v_POLY_globals1_position;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nvarying float v_POLY_attribute_id;\n\n\n\n\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\n\nvarying vec2 vHighPrecisionZW;\n\nstruct SSSModel {\n\tbool isActive;\n\tvec3 color;\n\tfloat thickness;\n\tfloat power;\n\tfloat scale;\n\tfloat distortion;\n\tfloat ambient;\n\tfloat attenuation;\n};\n\nvoid RE_Direct_Scattering(\n\tconst in IncidentLight directLight,\n\tconst in GeometricContext geometry,\n\tconst in SSSModel sssModel,\n\tinout ReflectedLight reflectedLight\n\t){\n\tvec3 scatteringHalf = normalize(directLight.direction + (geometry.normal * sssModel.distortion));\n\tfloat scatteringDot = pow(saturate(dot(geometry.viewDir, -scatteringHalf)), sssModel.power) * sssModel.scale;\n\tvec3 scatteringIllu = (scatteringDot + sssModel.ambient) * (sssModel.color * (1.0-sssModel.thickness));\n\treflectedLight.directDiffuse += scatteringIllu * sssModel.attenuation * directLight.color;\n}\n\nvoid main() {\n\n\t#include <clipping_planes_fragment>\n\n\tvec4 diffuseColor = vec4( 1.0 );\n\n\t#if DEPTH_PACKING == 3200\n\n\t\tdiffuseColor.a = opacity;\n\n\t#endif\n\n\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\n\n\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\n\tfloat v_POLY_globals1_time = time;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\n\tfloat v_POLY_attribute2_val = v_POLY_attribute_id;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/constant1\n\tfloat v_POLY_constant1_val = 1.0;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/noise1\n\tfloat v_POLY_noise1_noise = 0.45*fbm_snoise_rotatingSpheres_MAT_meshPhysicalBuilder1_noise1((v_POLY_globals1_position*vec3(100.0, 100.0, 100.0))+vec3(0.0, 0.0, 0.0));\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/round1\n\tfloat v_POLY_round1_val = sign(v_POLY_attribute2_val)*floor(abs(v_POLY_attribute2_val)+0.5);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/add1\n\tfloat v_POLY_add1_sum = (v_POLY_constant1_val + v_POLY_noise1_noise + 0.0);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_round1_val, 0.0);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/random1\n\tfloat v_POLY_random1_rand = rand(v_POLY_floatToVec2_1_vec2);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/output1\n\tfloat POLY_metalness = 1.0;\n\tfloat POLY_roughness = v_POLY_random1_rand;\n\tvec3 POLY_emissive = vec3(1.0, 1.0, 1.0);\n\tSSSModel POLY_SSSModel = SSSModel(/*isActive*/false,/*color*/vec3(1.0, 1.0, 1.0), /*thickness*/0.1, /*power*/2.0, /*scale*/16.0, /*distortion*/0.1,/*ambient*/0.4,/*attenuation*/0.8 );\n\tfloat POLY_transmission = 1.0;\n\tfloat POLY_thickness = v_POLY_add1_sum;\n\n\n\n\n\t// INSERT BODY\n\t// the new body lines should be added before the alphatest_fragment\n\t// so that alpha is set before (which is really how it would be set if the alphamap_fragment above was used by the material node parameters)\n\n\t#include <alphatest_fragment>\n\n\t#include <logdepthbuf_fragment>\n\n\n\t// Higher precision equivalent of gl_FragCoord.z. This assumes depthRange has been left to its default values.\n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\n\t#if DEPTH_PACKING == 3200\n\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), diffuseColor.a );\n\n\t#elif DEPTH_PACKING == 3201\n\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\n\t#endif\n\n}\n","customDistanceMaterial.vertex":"#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/rotate1\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n\n\n\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nuniform float time;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nvarying vec3 v_POLY_globals1_position;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nvarying float v_POLY_attribute_id;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute1\nattribute vec3 instancePosition;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nattribute float id;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/instanceTransform1\nattribute vec4 instanceOrientation;\nattribute vec3 instanceScale;\n\n\n\n\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n// removed:\n//\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n// removed:\n//\t#include <begin_vertex>\n\n\n\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute1\n\tvec3 v_POLY_attribute1_val = instancePosition;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\n\tv_POLY_globals1_position = vec3(position);\n\tfloat v_POLY_globals1_time = time;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\n\tv_POLY_attribute_id = float(id);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/length1\n\tfloat v_POLY_length1_val = length(v_POLY_attribute1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/normalize1\n\tvec3 v_POLY_normalize1_normalized = normalize(v_POLY_attribute1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/multAdd1\n\tfloat v_POLY_multAdd1_val = (0.51*(v_POLY_globals1_time + 0.0)) + 0.0;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/rotate1\n\tvec3 v_POLY_rotate1_val = rotateWithAxisAngle(v_POLY_normalize1_normalized, vec3(0.0, 0.0, 1.0), v_POLY_multAdd1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/mult1\n\tvec3 v_POLY_mult1_product = (v_POLY_length1_val * v_POLY_rotate1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/instanceTransform1\n\tvec3 v_POLY_instanceTransform1_position = vec3(position);\n\tv_POLY_instanceTransform1_position *= instanceScale;\n\tv_POLY_instanceTransform1_position = rotateWithQuat( v_POLY_instanceTransform1_position, instanceOrientation );\n\tv_POLY_instanceTransform1_position += v_POLY_mult1_product;\n\tvec3 v_POLY_instanceTransform1_normal = vec3(normal);\n\tv_POLY_instanceTransform1_normal = rotateWithQuat( v_POLY_instanceTransform1_normal, instanceOrientation );\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/output1\n\tvec3 transformed = v_POLY_instanceTransform1_position;\n\tvec3 objectNormal = v_POLY_instanceTransform1_normal;\n\t#ifdef USE_TANGENT\n\t\tvec3 objectTangent = vec3( tangent.xyz );\n\t#endif\n\n\n\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}","customDistanceMaterial.fragment":"\n// INSERT DEFINES\n\n#define DISTANCE\n\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n\n#include <common>\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/noise1\n// Modulo 289 without a division (only multiplications)\nfloat mod289(float x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec2 mod289(vec2 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec3 mod289(vec3 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec4 mod289(vec4 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n// Modulo 7 without a division\nvec3 mod7(vec3 x) {\n return x - floor(x * (1.0 / 7.0)) * 7.0;\n}\n\n// Permutation polynomial: (34x^2 + x) mod 289\nfloat permute(float x) {\n return mod289(((x*34.0)+1.0)*x);\n}\nvec3 permute(vec3 x) {\n return mod289((34.0 * x + 1.0) * x);\n}\nvec4 permute(vec4 x) {\n return mod289(((x*34.0)+1.0)*x);\n}\n\nfloat taylorInvSqrt(float r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\nvec4 taylorInvSqrt(vec4 r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\n\nvec2 fade(vec2 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\nvec3 fade(vec3 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\nvec4 fade(vec4 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\n//\n// Description : Array and textureless GLSL 2D/3D/4D simplex \n// noise functions.\n// Author : Ian McEwan, Ashima Arts.\n// Maintainer : stegu\n// Lastmod : 20110822 (ijm)\n// License : Copyright (C) 2011 Ashima Arts. All rights reserved.\n// Distributed under the MIT License. See LICENSE file.\n// https://github.com/ashima/webgl-noise\n// https://github.com/stegu/webgl-noise\n// \n\n\n\nfloat snoise(vec3 v)\n { \n const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\n// First corner\n vec3 i = floor(v + dot(v, C.yyy) );\n vec3 x0 = v - i + dot(i, C.xxx) ;\n\n// Other corners\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min( g.xyz, l.zxy );\n vec3 i2 = max( g.xyz, l.zxy );\n\n // x0 = x0 - 0.0 + 0.0 * C.xxx;\n // x1 = x0 - i1 + 1.0 * C.xxx;\n // x2 = x0 - i2 + 2.0 * C.xxx;\n // x3 = x0 - 1.0 + 3.0 * C.xxx;\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y\n vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y\n\n// Permutations\n i = mod289(i); \n vec4 p = permute( permute( permute( \n i.z + vec4(0.0, i1.z, i2.z, 1.0 ))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) \n + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));\n\n// Gradients: 7x7 points over a square, mapped onto an octahedron.\n// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)\n float n_ = 0.142857142857; // 1.0/7.0\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)\n\n vec4 x = x_ *ns.x + ns.yyyy;\n vec4 y = y_ *ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n\n vec4 b0 = vec4( x.xy, y.xy );\n vec4 b1 = vec4( x.zw, y.zw );\n\n //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;\n //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;\n vec4 s0 = floor(b0)*2.0 + 1.0;\n vec4 s1 = floor(b1)*2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;\n\n vec3 p0 = vec3(a0.xy,h.x);\n vec3 p1 = vec3(a0.zw,h.y);\n vec3 p2 = vec3(a1.xy,h.z);\n vec3 p3 = vec3(a1.zw,h.w);\n\n//Normalise gradients\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n// Mix final noise value\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), \n dot(p2,x2), dot(p3,x3) ) );\n }\n\n\nfloat fbm_snoise_rotatingSpheres_MAT_meshPhysicalBuilder1_noise1(in vec3 st) {\n\tfloat value = 0.0;\n\tfloat amplitude = 1.0;\n\tfor (int i = 0; i < 3; i++) {\n\t\tvalue += amplitude * snoise(st);\n\t\tst *= 2.0;\n\t\tamplitude *= 0.5;\n\t}\n\treturn value;\n}\n\n\n\n\n\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nuniform float time;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nvarying vec3 v_POLY_globals1_position;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nvarying float v_POLY_attribute_id;\n\n\n\n\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <clipping_planes_pars_fragment>\n\nstruct SSSModel {\n\tbool isActive;\n\tvec3 color;\n\tfloat thickness;\n\tfloat power;\n\tfloat scale;\n\tfloat distortion;\n\tfloat ambient;\n\tfloat attenuation;\n};\n\nvoid RE_Direct_Scattering(\n\tconst in IncidentLight directLight,\n\tconst in GeometricContext geometry,\n\tconst in SSSModel sssModel,\n\tinout ReflectedLight reflectedLight\n\t){\n\tvec3 scatteringHalf = normalize(directLight.direction + (geometry.normal * sssModel.distortion));\n\tfloat scatteringDot = pow(saturate(dot(geometry.viewDir, -scatteringHalf)), sssModel.power) * sssModel.scale;\n\tvec3 scatteringIllu = (scatteringDot + sssModel.ambient) * (sssModel.color * (1.0-sssModel.thickness));\n\treflectedLight.directDiffuse += scatteringIllu * sssModel.attenuation * directLight.color;\n}\n\nvoid main() {\n\n\t#include <clipping_planes_fragment>\n\n\tvec4 diffuseColor = vec4( 1.0 );\n\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\n\n\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\n\tfloat v_POLY_globals1_time = time;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\n\tfloat v_POLY_attribute2_val = v_POLY_attribute_id;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/constant1\n\tfloat v_POLY_constant1_val = 1.0;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/noise1\n\tfloat v_POLY_noise1_noise = 0.45*fbm_snoise_rotatingSpheres_MAT_meshPhysicalBuilder1_noise1((v_POLY_globals1_position*vec3(100.0, 100.0, 100.0))+vec3(0.0, 0.0, 0.0));\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/round1\n\tfloat v_POLY_round1_val = sign(v_POLY_attribute2_val)*floor(abs(v_POLY_attribute2_val)+0.5);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/add1\n\tfloat v_POLY_add1_sum = (v_POLY_constant1_val + v_POLY_noise1_noise + 0.0);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_round1_val, 0.0);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/random1\n\tfloat v_POLY_random1_rand = rand(v_POLY_floatToVec2_1_vec2);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/output1\n\tfloat POLY_metalness = 1.0;\n\tfloat POLY_roughness = v_POLY_random1_rand;\n\tvec3 POLY_emissive = vec3(1.0, 1.0, 1.0);\n\tSSSModel POLY_SSSModel = SSSModel(/*isActive*/false,/*color*/vec3(1.0, 1.0, 1.0), /*thickness*/0.1, /*power*/2.0, /*scale*/16.0, /*distortion*/0.1,/*ambient*/0.4,/*attenuation*/0.8 );\n\tfloat POLY_transmission = 1.0;\n\tfloat POLY_thickness = v_POLY_add1_sum;\n\n\n\n\n\t// INSERT BODY\n\n\t#include <alphatest_fragment>\n\n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist ); // clamp to [ 0, 1 ]\n\n\tgl_FragColor = packDepthToRGBA( dist );\n\n}\n","customDepthDOFMaterial.vertex":"#include <common>\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/rotate1\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n\n\n\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nuniform float time;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nvarying vec3 v_POLY_globals1_position;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nvarying float v_POLY_attribute_id;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute1\nattribute vec3 instancePosition;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nattribute float id;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/instanceTransform1\nattribute vec4 instanceOrientation;\nattribute vec3 instanceScale;\n\n\n\n\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n// removed:\n//\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n// removed:\n//\t#include <begin_vertex>\n\n\n\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute1\n\tvec3 v_POLY_attribute1_val = instancePosition;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\n\tv_POLY_globals1_position = vec3(position);\n\tfloat v_POLY_globals1_time = time;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\n\tv_POLY_attribute_id = float(id);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/length1\n\tfloat v_POLY_length1_val = length(v_POLY_attribute1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/normalize1\n\tvec3 v_POLY_normalize1_normalized = normalize(v_POLY_attribute1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/multAdd1\n\tfloat v_POLY_multAdd1_val = (0.51*(v_POLY_globals1_time + 0.0)) + 0.0;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/rotate1\n\tvec3 v_POLY_rotate1_val = rotateWithAxisAngle(v_POLY_normalize1_normalized, vec3(0.0, 0.0, 1.0), v_POLY_multAdd1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/mult1\n\tvec3 v_POLY_mult1_product = (v_POLY_length1_val * v_POLY_rotate1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/instanceTransform1\n\tvec3 v_POLY_instanceTransform1_position = vec3(position);\n\tv_POLY_instanceTransform1_position *= instanceScale;\n\tv_POLY_instanceTransform1_position = rotateWithQuat( v_POLY_instanceTransform1_position, instanceOrientation );\n\tv_POLY_instanceTransform1_position += v_POLY_mult1_product;\n\tvec3 v_POLY_instanceTransform1_normal = vec3(normal);\n\tv_POLY_instanceTransform1_normal = rotateWithQuat( v_POLY_instanceTransform1_normal, instanceOrientation );\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/output1\n\tvec3 transformed = v_POLY_instanceTransform1_position;\n\tvec3 objectNormal = v_POLY_instanceTransform1_normal;\n\t#ifdef USE_TANGENT\n\t\tvec3 objectTangent = vec3( tangent.xyz );\n\t#endif\n\n\n\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvHighPrecisionZW = gl_Position.zw;\n}","customDepthDOFMaterial.fragment":"\n// INSERT DEFINES\n\n\n#if DEPTH_PACKING == 3200\n\n\tuniform float opacity;\n\n#endif\n\n#include <common>\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/noise1\n// Modulo 289 without a division (only multiplications)\nfloat mod289(float x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec2 mod289(vec2 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec3 mod289(vec3 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec4 mod289(vec4 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n// Modulo 7 without a division\nvec3 mod7(vec3 x) {\n return x - floor(x * (1.0 / 7.0)) * 7.0;\n}\n\n// Permutation polynomial: (34x^2 + x) mod 289\nfloat permute(float x) {\n return mod289(((x*34.0)+1.0)*x);\n}\nvec3 permute(vec3 x) {\n return mod289((34.0 * x + 1.0) * x);\n}\nvec4 permute(vec4 x) {\n return mod289(((x*34.0)+1.0)*x);\n}\n\nfloat taylorInvSqrt(float r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\nvec4 taylorInvSqrt(vec4 r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\n\nvec2 fade(vec2 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\nvec3 fade(vec3 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\nvec4 fade(vec4 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\n//\n// Description : Array and textureless GLSL 2D/3D/4D simplex \n// noise functions.\n// Author : Ian McEwan, Ashima Arts.\n// Maintainer : stegu\n// Lastmod : 20110822 (ijm)\n// License : Copyright (C) 2011 Ashima Arts. All rights reserved.\n// Distributed under the MIT License. See LICENSE file.\n// https://github.com/ashima/webgl-noise\n// https://github.com/stegu/webgl-noise\n// \n\n\n\nfloat snoise(vec3 v)\n { \n const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\n// First corner\n vec3 i = floor(v + dot(v, C.yyy) );\n vec3 x0 = v - i + dot(i, C.xxx) ;\n\n// Other corners\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min( g.xyz, l.zxy );\n vec3 i2 = max( g.xyz, l.zxy );\n\n // x0 = x0 - 0.0 + 0.0 * C.xxx;\n // x1 = x0 - i1 + 1.0 * C.xxx;\n // x2 = x0 - i2 + 2.0 * C.xxx;\n // x3 = x0 - 1.0 + 3.0 * C.xxx;\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y\n vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y\n\n// Permutations\n i = mod289(i); \n vec4 p = permute( permute( permute( \n i.z + vec4(0.0, i1.z, i2.z, 1.0 ))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) \n + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));\n\n// Gradients: 7x7 points over a square, mapped onto an octahedron.\n// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)\n float n_ = 0.142857142857; // 1.0/7.0\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)\n\n vec4 x = x_ *ns.x + ns.yyyy;\n vec4 y = y_ *ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n\n vec4 b0 = vec4( x.xy, y.xy );\n vec4 b1 = vec4( x.zw, y.zw );\n\n //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;\n //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;\n vec4 s0 = floor(b0)*2.0 + 1.0;\n vec4 s1 = floor(b1)*2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;\n\n vec3 p0 = vec3(a0.xy,h.x);\n vec3 p1 = vec3(a0.zw,h.y);\n vec3 p2 = vec3(a1.xy,h.z);\n vec3 p3 = vec3(a1.zw,h.w);\n\n//Normalise gradients\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n// Mix final noise value\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), \n dot(p2,x2), dot(p3,x3) ) );\n }\n\n\nfloat fbm_snoise_rotatingSpheres_MAT_meshPhysicalBuilder1_noise1(in vec3 st) {\n\tfloat value = 0.0;\n\tfloat amplitude = 1.0;\n\tfor (int i = 0; i < 3; i++) {\n\t\tvalue += amplitude * snoise(st);\n\t\tst *= 2.0;\n\t\tamplitude *= 0.5;\n\t}\n\treturn value;\n}\n\n\n\n\n\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nuniform float time;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nvarying vec3 v_POLY_globals1_position;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nvarying float v_POLY_attribute_id;\n\n\n\n\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\n\nvarying vec2 vHighPrecisionZW;\n\nstruct SSSModel {\n\tbool isActive;\n\tvec3 color;\n\tfloat thickness;\n\tfloat power;\n\tfloat scale;\n\tfloat distortion;\n\tfloat ambient;\n\tfloat attenuation;\n};\n\nvoid RE_Direct_Scattering(\n\tconst in IncidentLight directLight,\n\tconst in GeometricContext geometry,\n\tconst in SSSModel sssModel,\n\tinout ReflectedLight reflectedLight\n\t){\n\tvec3 scatteringHalf = normalize(directLight.direction + (geometry.normal * sssModel.distortion));\n\tfloat scatteringDot = pow(saturate(dot(geometry.viewDir, -scatteringHalf)), sssModel.power) * sssModel.scale;\n\tvec3 scatteringIllu = (scatteringDot + sssModel.ambient) * (sssModel.color * (1.0-sssModel.thickness));\n\treflectedLight.directDiffuse += scatteringIllu * sssModel.attenuation * directLight.color;\n}\n\nvoid main() {\n\n\t#include <clipping_planes_fragment>\n\n\tvec4 diffuseColor = vec4( 1.0 );\n\n\t#if DEPTH_PACKING == 3200\n\n\t\tdiffuseColor.a = opacity;\n\n\t#endif\n\n\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\n\n\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\n\tfloat v_POLY_globals1_time = time;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\n\tfloat v_POLY_attribute2_val = v_POLY_attribute_id;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/constant1\n\tfloat v_POLY_constant1_val = 1.0;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/noise1\n\tfloat v_POLY_noise1_noise = 0.45*fbm_snoise_rotatingSpheres_MAT_meshPhysicalBuilder1_noise1((v_POLY_globals1_position*vec3(100.0, 100.0, 100.0))+vec3(0.0, 0.0, 0.0));\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/round1\n\tfloat v_POLY_round1_val = sign(v_POLY_attribute2_val)*floor(abs(v_POLY_attribute2_val)+0.5);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/add1\n\tfloat v_POLY_add1_sum = (v_POLY_constant1_val + v_POLY_noise1_noise + 0.0);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_round1_val, 0.0);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/random1\n\tfloat v_POLY_random1_rand = rand(v_POLY_floatToVec2_1_vec2);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/output1\n\tfloat POLY_metalness = 1.0;\n\tfloat POLY_roughness = v_POLY_random1_rand;\n\tvec3 POLY_emissive = vec3(1.0, 1.0, 1.0);\n\tSSSModel POLY_SSSModel = SSSModel(/*isActive*/false,/*color*/vec3(1.0, 1.0, 1.0), /*thickness*/0.1, /*power*/2.0, /*scale*/16.0, /*distortion*/0.1,/*ambient*/0.4,/*attenuation*/0.8 );\n\tfloat POLY_transmission = 1.0;\n\tfloat POLY_thickness = v_POLY_add1_sum;\n\n\n\n\n\t// INSERT BODY\n\t// the new body lines should be added before the alphatest_fragment\n\t// so that alpha is set before (which is really how it would be set if the alphamap_fragment above was used by the material node parameters)\n\n\t#include <alphatest_fragment>\n\n\t#include <logdepthbuf_fragment>\n\n\n\t// Higher precision equivalent of gl_FragCoord.z. This assumes depthRange has been left to its default values.\n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\n\t#if DEPTH_PACKING == 3200\n\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), diffuseColor.a );\n\n\t#elif DEPTH_PACKING == 3201\n\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\n\t#endif\n\n}\n"}}}
Code editor
{"multiple_panel":{"split_ratio":0.5,"split_panel0":{"split_ratio":0.5,"split_panel0":{"panelTypes":["viewer"],"currentPanelIndex":0,"panel_data":{"camera":"/perspectiveCamera_MAIN","linkIndex":1}},"split_panel1":{"panelTypes":["params"],"currentPanelIndex":0,"panel_data":{"active_folder":null,"linkIndex":1}},"split_mode":"vertical"},"split_panel1":{"panelTypes":["network","params","viewer"],"currentPanelIndex":0,"panel_data":{"camera":{"position":{"x":-357.56578639642885,"y":187.8362839979532},"zoom":0.7560000000000002},"history":{"2":{"position":{"x":255.6203866432337,"y":-135.39191564147626},"zoom":0.6290000000000001},"3":{"position":{"x":-48,"y":-22},"zoom":0.5},"6":{"position":{"x":11.339999999999996,"y":-96.49999999999999},"zoom":0.6172839506172841},"9":{"position":{"x":-32,"y":-88},"zoom":0.5},"102":{"position":{"x":25,"y":-150},"zoom":0.5690000000000001},"131":{"position":{"x":-59.04899999999998,"y":-65.1854},"zoom":0.8467543904215146},"298":{"position":{"x":-250.462,"y":5.910000000000017},"zoom":0.6172839506172841},"354":{"position":{"x":-56,"y":-370},"zoom":0.5},"358":{"position":{"x":-56,"y":-370},"zoom":0.5},"361":{"position":{"x":-163.35616438356158,"y":-607.8767123287671},"zoom":0.5840000000000001},"362":{"position":{"x":78.45786963434023,"y":-1085.0556438791732},"zoom":0.6290000000000001},"382":{"position":{"x":-8,"y":-102},"zoom":0.5},"1083":{"position":{"x":92,"y":-400},"zoom":0.5},"1090":{"position":{"x":92,"y":-400},"zoom":0.5},"1103":{"position":{"x":-357.56578639642885,"y":187.8362839979532},"zoom":0.7560000000000002}},"linkIndex":1}},"split_mode":"horizontal"},"currentNodes":["/musicBoxes/actor1","/","/","/","/","/","/","/"],"navigationHistory":{"nodePaths":{"1":["/","/COP","/","/musicBoxes","/musicBoxes/actor1"],"2":["/"],"3":["/"],"4":["/"],"5":["/"],"6":["/"],"7":["/"],"8":["/"]},"index":{"1":4,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0}},"fullscreenPanelId":null,"saveOptions":{"createExport":true,"skipExportSinceRemoteAssetsPresents":false,"compressJs":true,"createZip":true,"publishToIntegrations":false},"paramsModal":[]}
Used nodes
actor/add;actor/floatToVec3;actor/getObjectAttribute;actor/mult;actor/onObjectHover;actor/onTick;actor/playInstrumentNote;actor/setObjectAttribute;actor/setObjectRotation;actor/triggerFilter;anim/duration;anim/easing;anim/null;anim/operation;anim/position;anim/propertyName;anim/propertyValue;anim/switch;anim/target;audio/Synth;audio/chorus;audio/envelope;audio/monoSynth;audio/null;audio/pitchShift;audio/playInstrument;audio/polySynth;audio/reverb;audio/switch;audio/volume;cop/envMap;cop/image;cop/imageEXR;event/animation;event/audio;event/cameraOrbitControls;event/intersectData;event/mouse;event/nodeCook;event/param;event/raycast;event/scene;event/setParam;event/viewer;mat/meshPhysicalBuilder;mat/meshStandard;obj/audioListener;obj/contactShadow;obj/copNetwork;obj/geo;obj/hemisphereLight;obj/null;obj/perspectiveCamera;obj/polarTransform;obj/positionalAudio;obj/spotLight;rop/WebGLRenderer;sop/actor;sop/animationsNetwork;sop/attribCreate;sop/attribPromote;sop/attribRemap;sop/audioNotes;sop/circle;sop/copy;sop/eventsNetwork;sop/instance;sop/line;sop/material;sop/materialsNetwork;sop/objectProperties;sop/palette;sop/plane;sop/planeHelper;sop/renderersNetwork;sop/roundedBox;sop/scatter;sop/skin;sop/sphere;sop/transform;sop/tube
Used operations
Used modules
Used assemblers
GL_MESH_PHYSICAL
Used integrations
[]
Used assets
Nodes map
{"/hemisphereLight1":"obj/hemisphereLight","/spotLight1":"obj/spotLight","/COP":"obj/copNetwork","/COP/envMap":"cop/envMap","/COP/imageEnv":"cop/imageEXR","/COP/imageUv":"cop/image","/set":"obj/geo","/set/MAT":"sop/materialsNetwork","/set/MAT/meshStandard1":"mat/meshStandard","/set/circle1":"sop/circle","/set/material1":"sop/material","/set/skin1":"sop/skin","/set/transform1":"sop/transform","/set/transform2":"sop/transform","/set/transform3":"sop/transform","/set/transform4":"sop/transform","/set/transform5":"sop/transform","/set/transform6":"sop/transform","/set/transform7":"sop/transform","/set/transform8":"sop/transform","/set/transform9":"sop/transform","/polarTransform1":"obj/polarTransform","/gridHelper":"obj/geo","/gridHelper/plane1":"sop/plane","/gridHelper/planeHelper1":"sop/planeHelper","/spotLight2":"obj/spotLight","/polarTransform2":"obj/polarTransform","/null1":"obj/null","/contactShadow1":"obj/contactShadow","/positionalAudio1":"obj/positionalAudio","/positionalAudio1/OUT":"audio/null","/positionalAudio1/Synth1":"audio/Synth","/positionalAudio1/chorus1":"audio/chorus","/positionalAudio1/chorus2":"audio/chorus","/positionalAudio1/envelope1":"audio/envelope","/positionalAudio1/monoSynth1":"audio/monoSynth","/positionalAudio1/pitchShift1":"audio/pitchShift","/positionalAudio1/playInstrument1":"audio/playInstrument","/positionalAudio1/polySynth1":"audio/polySynth","/positionalAudio1/reverb1":"audio/reverb","/positionalAudio1/reverb2":"audio/reverb","/positionalAudio1/switch1":"audio/switch","/positionalAudio1/switch2":"audio/switch","/positionalAudio1/volume1":"audio/volume","/audioListener1":"obj/audioListener","/musicBoxes":"obj/geo","/musicBoxes/ANIM":"sop/animationsNetwork","/musicBoxes/ANIM/PLAY":"anim/null","/musicBoxes/ANIM/PLAY1":"anim/null","/musicBoxes/ANIM/RESET":"anim/null","/musicBoxes/ANIM/RESET1":"anim/null","/musicBoxes/ANIM/duration1":"anim/duration","/musicBoxes/ANIM/duration2":"anim/duration","/musicBoxes/ANIM/duration3":"anim/duration","/musicBoxes/ANIM/duration5":"anim/duration","/musicBoxes/ANIM/easing1":"anim/easing","/musicBoxes/ANIM/easing2":"anim/easing","/musicBoxes/ANIM/easing3":"anim/easing","/musicBoxes/ANIM/easing4":"anim/easing","/musicBoxes/ANIM/operation1":"anim/operation","/musicBoxes/ANIM/operation2":"anim/operation","/musicBoxes/ANIM/position1":"anim/position","/musicBoxes/ANIM/position2":"anim/position","/musicBoxes/ANIM/position3":"anim/position","/musicBoxes/ANIM/position4":"anim/position","/musicBoxes/ANIM/propertyName1":"anim/propertyName","/musicBoxes/ANIM/propertyName2":"anim/propertyName","/musicBoxes/ANIM/propertyValue1":"anim/propertyValue","/musicBoxes/ANIM/propertyValue2":"anim/propertyValue","/musicBoxes/ANIM/propertyValue3":"anim/propertyValue","/musicBoxes/ANIM/propertyValue4":"anim/propertyValue","/musicBoxes/ANIM/switch1":"anim/switch","/musicBoxes/ANIM/target1":"anim/target","/musicBoxes/ANIM/target2":"anim/target","/musicBoxes/EVENTS":"sop/eventsNetwork","/musicBoxes/EVENTS/animation2":"event/animation","/musicBoxes/EVENTS/audio1":"event/audio","/musicBoxes/EVENTS/intersectData_ID":"event/intersectData","/musicBoxes/EVENTS/intersectData_NOTE":"event/intersectData","/musicBoxes/EVENTS/mouse1":"event/mouse","/musicBoxes/EVENTS/nodeCook1":"event/nodeCook","/musicBoxes/EVENTS/param4":"event/param","/musicBoxes/EVENTS/raycast1":"event/raycast","/musicBoxes/EVENTS/scene1":"event/scene","/musicBoxes/EVENTS/setParam1":"event/setParam","/musicBoxes/EVENTS/viewer1":"event/viewer","/musicBoxes/MAT":"sop/materialsNetwork","/musicBoxes/MAT/meshStandard1":"mat/meshStandard","/musicBoxes/actor1":"sop/actor","/musicBoxes/actor1/add1":"actor/add","/musicBoxes/actor1/floatToVec3_1":"actor/floatToVec3","/musicBoxes/actor1/getObjectAttribute1":"actor/getObjectAttribute","/musicBoxes/actor1/getObjectAttribute2":"actor/getObjectAttribute","/musicBoxes/actor1/mult1":"actor/mult","/musicBoxes/actor1/onEventObjectHovered1":"actor/onObjectHover","/musicBoxes/actor1/onEventTick1":"actor/onTick","/musicBoxes/actor1/playInstrumentNote1":"actor/playInstrumentNote","/musicBoxes/actor1/setObjectRotation1":"actor/setObjectRotation","/musicBoxes/actor1/triggerFilter1":"actor/triggerFilter","/musicBoxes/actor1/setObjectAttribute2":"actor/setObjectAttribute","/musicBoxes/attribCreate1":"sop/attribCreate","/musicBoxes/attribCreate2":"sop/attribCreate","/musicBoxes/attribCreate3":"sop/attribCreate","/musicBoxes/attribCreate4":"sop/attribCreate","/musicBoxes/attribCreate5":"sop/attribCreate","/musicBoxes/attribPromote1":"sop/attribPromote","/musicBoxes/attribRemap1":"sop/attribRemap","/musicBoxes/audioNotes1":"sop/audioNotes","/musicBoxes/copy1":"sop/copy","/musicBoxes/line1":"sop/line","/musicBoxes/material1":"sop/material","/musicBoxes/objectProperties1":"sop/objectProperties","/musicBoxes/palette2":"sop/palette","/musicBoxes/roundedBox1":"sop/roundedBox","/musicBoxes/transform1":"sop/transform","/musicBoxes/transform2":"sop/transform","/rotatingSpheres":"obj/geo","/rotatingSpheres/MAT":"sop/materialsNetwork","/rotatingSpheres/MAT/meshPhysicalBuilder1":"mat/meshPhysicalBuilder","/rotatingSpheres/instance1":"sop/instance","/rotatingSpheres/scatter1":"sop/scatter","/rotatingSpheres/sphere1":"sop/sphere","/rotatingSpheres/transform1":"sop/transform","/rotatingSpheres/tube1":"sop/tube","/perspectiveCamera_MAIN":"obj/perspectiveCamera","/perspectiveCamera_MAIN/events1":"sop/eventsNetwork","/perspectiveCamera_MAIN/events1/cameraOrbitControls1":"event/cameraOrbitControls","/perspectiveCamera_MAIN/renderersNetwork1":"sop/renderersNetwork","/perspectiveCamera_MAIN/renderersNetwork1/WebGLRenderer1":"rop/WebGLRenderer","/perspectiveCamera_DEBUG":"obj/perspectiveCamera","/perspectiveCamera_DEBUG/events1":"sop/eventsNetwork","/perspectiveCamera_DEBUG/events1/cameraOrbitControls2":"event/cameraOrbitControls","/null2":"obj/null"}
Js version
Editor version
Engine version
Name
*
Code
{"properties":{"frame":0,"maxFrame":600,"maxFrameLocked":false,"realtimeState":true,"mainCameraPath":"/perspectiveCamera_MAIN","versions":{"polygonjs":"1.2.21"}},"root":{"type":"root","nodes":{"hemisphereLight1":{"type":"hemisphereLight","flags":{"display":true}},"spotLight1":{"type":"spotLight","params":{"r":[90,0,0],"intensity":3,"angle":50.4,"penumbra":0.6,"decay":0.23,"shadowBias":0,"shadowRadius":60},"inputs":["polarTransform1"],"flags":{"display":true}},"COP":{"type":"copNetwork","nodes":{"envMap":{"type":"envMap","inputs":["imageEnv"]},"imageEnv":{"type":"imageEXR","params":{"url":"https://raw.githubusercontent.com/polygonjs/polygonjs-assets/master/textures/piz_compressed.exr"}},"imageUv":{"type":"image","params":{"url":"https://raw.githubusercontent.com/polygonjs/polygonjs-assets/master/textures/uv.jpg","tflipY":true}}}},"set":{"type":"geo","nodes":{"MAT":{"type":"materialsNetwork","nodes":{"meshStandard1":{"type":"meshStandard","params":{"useEnvMap":true,"envMap":"../../../COP/envMap","roughness":0.87,"useFog":true}}}},"circle1":{"type":"circle","params":{"radius":0.5,"segments":100,"connectLastPoint":false,"arcAngle":90,"direction":[0,0,1]}},"material1":{"type":"material","params":{"material":"../MAT/meshStandard1"},"inputs":["transform9"]},"skin1":{"type":"skin","inputs":["transform6","transform1"]},"transform1":{"type":"transform","params":{"t":["-ch(\"../transform6/tx\")",0,0]},"inputs":["transform5"]},"transform2":{"type":"transform","params":{"t":[0.5,0.5,0],"r":[0,90,-90]},"inputs":["circle1"]},"transform3":{"type":"transform","params":{"t":[0,"-bbox(0, 'min').y",0]},"inputs":["transform2"]},"transform4":{"type":"transform","params":{"group":"0","t":[0,0,50]},"inputs":["transform3"]},"transform5":{"type":"transform","params":{"group":"`pointsCount(0)-1`","t":[0,50,0]},"inputs":["transform4"]},"transform6":{"type":"transform","params":{"t":[50,0,0]},"inputs":["transform5"]},"transform7":{"type":"transform","params":{"t":[0,0,-1.7127319559331746]},"inputs":["material1"]},"transform8":{"type":"transform","params":{"scale":5.4},"inputs":["transform7"],"flags":{"display":true}},"transform9":{"type":"transform","params":{"s":[4,1,1]},"inputs":["skin1"]}},"flags":{"display":true}},"polarTransform1":{"type":"polarTransform","params":{"longitude":50.4,"latitude":25.2,"depth":15.6},"inputs":["null1"],"flags":{"display":false}},"gridHelper":{"type":"geo","nodes":{"plane1":{"type":"plane"},"planeHelper1":{"type":"planeHelper","flags":{"display":true}}},"flags":{"display":false}},"spotLight2":{"type":"spotLight","params":{"r":[90,0,0],"penumbra":0.4,"decay":0.43,"shadowBias":0,"shadowRadius":7.2},"inputs":["polarTransform2"],"flags":{"display":true}},"polarTransform2":{"type":"polarTransform","params":{"longitude":327.6,"latitude":50.4,"depth":22},"inputs":["null1"],"flags":{"display":false}},"null1":{"type":"null","params":{"t":[0,0,-7.239058048075525]},"flags":{"display":false}},"contactShadow1":{"type":"contactShadow","params":{"t":[-0.7603034971525082,0.3277860273265716,0.5045394655675899],"r":[0,37.843408801064925,0],"dist":6.5,"planeSize":[26.3,6.3],"blur":14,"blur2":30,"darkness":0.78},"flags":{"display":false}},"positionalAudio1":{"type":"positionalAudio","nodes":{"OUT":{"type":"null","inputs":["switch2"]},"Synth1":{"type":"Synth"},"chorus1":{"type":"chorus","params":{"frequency":1.2},"inputs":["monoSynth1"]},"chorus2":{"type":"chorus","params":{"frequency":1.2},"inputs":["pitchShift1"]},"envelope1":{"type":"envelope"},"monoSynth1":{"type":"monoSynth","inputs":["envelope1"]},"pitchShift1":{"type":"pitchShift","params":{"pitch":4},"inputs":["monoSynth1"]},"playInstrument1":{"type":"playInstrument","params":{"note":"B4","startOctave":3,"updateNoteFromInstrument":true},"inputs":["OUT"]},"polySynth1":{"type":"polySynth"},"reverb1":{"type":"reverb","params":{"preDelay":0.06},"inputs":["monoSynth1"]},"reverb2":{"type":"reverb","params":{"decay":5.0005,"preDelay":0.12},"inputs":["monoSynth1"]},"switch1":{"type":"switch","inputs":["monoSynth1"]},"switch2":{"type":"switch","params":{"input":3},"inputs":["volume1","reverb2","chorus1","chorus2"]},"volume1":{"type":"volume","params":{"volume":10.8},"inputs":["reverb1"]}},"params":{"t":[0,4.693410955934931,0],"audioNode":"OUT","showHelper":false},"inputs":["musicBoxes"],"flags":{"display":true}},"audioListener1":{"type":"audioListener","inputs":["perspectiveCamera_MAIN"],"flags":{"display":true}},"musicBoxes":{"type":"geo","nodes":{"ANIM":{"type":"animationsNetwork","nodes":{"PLAY":{"type":"null","inputs":["operation1"]},"PLAY1":{"type":"null","inputs":["operation2"]},"RESET":{"type":"null","inputs":["position2"]},"RESET1":{"type":"null","inputs":["position4"]},"duration1":{"type":"duration","params":{"duration":1.4}},"duration2":{"type":"duration"},"duration3":{"type":"duration","params":{"duration":5.8}},"duration5":{"type":"duration"},"easing1":{"type":"easing","params":{"name":3,"inOut":2},"inputs":["duration5"]},"easing2":{"type":"easing","params":{"name":3,"inOut":2},"inputs":["duration2"]},"easing3":{"type":"easing","params":{"name":7},"inputs":["duration1"]},"easing4":{"type":"easing","params":{"name":6},"inputs":["duration3"]},"operation1":{"type":"operation","params":{"operation":1},"inputs":["position1"]},"operation2":{"type":"operation","params":{"operation":1},"inputs":["propertyValue3"]},"position1":{"type":"position","params":{"offset":0.05},"inputs":["propertyValue1"]},"position2":{"type":"position","inputs":["propertyValue2"]},"position3":{"type":"position","params":{"offset":0.05},"inputs":["propertyValue3"]},"position4":{"type":"position","inputs":["propertyValue4"]},"propertyName1":{"type":"propertyName","params":{"name":"rotation.x"},"inputs":["target1"]},"propertyName2":{"type":"propertyName","params":{"name":"rotation.x"},"inputs":["target2"]},"propertyValue1":{"type":"propertyValue","params":{"size":1,"value1":"$PI"},"inputs":["propertyName1"]},"propertyValue2":{"type":"propertyValue","params":{"size":1},"inputs":["propertyName1"]},"propertyValue3":{"type":"propertyValue","params":{"size":1,"value1":"$PI"},"inputs":["propertyName2"]},"propertyValue4":{"type":"propertyValue","params":{"size":1},"inputs":["propertyName2"]},"switch1":{"type":"switch","params":{"input":1},"inputs":["easing3","easing2","easing4"]},"target1":{"type":"target","params":{"objectMask":"*mainBox*"},"inputs":["switch1"]},"target2":{"type":"target","params":{"objectMask":"*mainBox_-1"},"inputs":["switch1"]}}},"EVENTS":{"type":"eventsNetwork","nodes":{"animation2":{"type":"animation","params":{"animation":"../../ANIM/PLAY1","stopsPreviousAnim":false},"inputs":[{"index":0,"node":"setParam1","output":"output"}]},"audio1":{"type":"audio","params":{"audio":"../../../positionalAudio1/OUT","note":"`ch(\"../intersectData_NOTE/attributeValues\")`"},"inputs":[{"index":0,"node":"param4","output":"valueChanged"}]},"intersectData_ID":{"type":"intersectData","params":{"attributeValue1":-1},"inputs":[{"index":0,"node":"raycast1","output":"hit"},{"index":1,"node":"raycast1","output":"miss"}]},"intersectData_NOTE":{"type":"intersectData","params":{"attributeName":"note","attributeType":1,"attributeValue1":-1},"inputs":[{"index":0,"node":"raycast1","output":"hit"},{"index":1,"node":"raycast1","output":"miss"}]},"mouse1":{"type":"mouse","params":{"mousedown":false,"mouseup":false}},"nodeCook1":{"type":"nodeCook","params":{"mask":"/rotatingBoxes/transform1","registerOnlyFirstCooks":false}},"param4":{"type":"param","params":{"param":"../intersectData_ID/attributeValue1","float":-1}},"raycast1":{"type":"raycast","params":{"mouse":[0.8715203426124196,-0.9656769390581716],"objectMask":"*mainBox*","traverseChildren":false,"position":[-5.394395355515165,4.248429965108464,4.7225804511378],"geoAttributeValue1":8},"inputs":[null,null,{"index":2,"node":"nodeCook1","output":"all"}]},"scene1":{"type":"scene"},"setParam1":{"type":"setParam","params":{"param":"/musicBoxes/ANIM/target2/objectMask","type":6,"string":"*mainBox_`ch(\"../intersectData_ID/attributeValue1\")`"},"inputs":[{"index":0,"node":"param4","output":"valueChanged"}]},"viewer1":{"type":"viewer","inputs":[{"index":0,"node":"raycast1","output":"hit"},{"index":1,"node":"raycast1","output":"miss"}]}}},"MAT":{"type":"materialsNetwork","nodes":{"meshStandard1":{"type":"meshStandard","params":{"useVertexColors":true,"useEnvMap":true,"envMap":"../../../COP/envMap","envMapIntensity":1.8,"metalness":0.16,"roughness":0.4,"useFog":true}}}},"actor1":{"type":"actor","nodes":{"add1":{"type":"add","params":{"add0":{"type":"float","default_value":0,"options":{"spare":true,"editable":false}},"add1":{"type":"float","default_value":0,"options":{"spare":true,"editable":true},"raw_input":1}},"inputs":[{"index":0,"node":"getObjectAttribute1","output":"val"}],"connection_points":{"in":[{"name":"add0","type":"float","isArray":false},{"name":"add1","type":"float","isArray":false}],"out":[{"name":"sum","type":"float","isArray":false}]}},"floatToVec3_1":{"type":"floatToVec3","params":{"x":{"overriden_options":{}},"y":{"overriden_options":{}},"z":{"overriden_options":{}}},"inputs":[{"index":0,"node":"mult1","output":"product"}]},"getObjectAttribute1":{"type":"getObjectAttribute","params":{"attribName":"rotationsCount"},"connection_points":{"in":[{"name":"Object3D","type":"Object3D","isArray":false}],"out":[{"name":"val","type":"float","isArray":false}]}},"getObjectAttribute2":{"type":"getObjectAttribute","params":{"attribName":"note","type":4},"connection_points":{"in":[{"name":"Object3D","type":"Object3D","isArray":false}],"out":[{"name":"val","type":"string","isArray":false}]}},"mult1":{"type":"mult","params":{"mult0":{"type":"float","default_value":1,"options":{"spare":true,"editable":false}},"mult1":{"type":"float","default_value":1,"options":{"spare":true,"editable":true},"raw_input":"$PI*0.5"}},"inputs":[{"index":0,"node":"getObjectAttribute1","output":"val"}],"connection_points":{"in":[{"name":"mult0","type":"float","isArray":false},{"name":"mult1","type":"float","isArray":false}],"out":[{"name":"product","type":"float","isArray":false}]}},"onEventObjectHovered1":{"type":"onObjectHover"},"onEventTick1":{"type":"onTick"},"playInstrumentNote1":{"type":"playInstrumentNote","params":{"node":"../../../positionalAudio1/OUT","note":{"overriden_options":{}},"duration":{"overriden_options":{}}},"maxInputsCount":4,"inputs":[{"index":0,"node":"triggerFilter1","output":"trigger"},null,{"index":2,"node":"getObjectAttribute2","output":"val"}]},"setObjectRotation1":{"type":"setObjectRotation","params":{"rotation":{"overriden_options":{}},"lerp":{"raw_input":0.14,"overriden_options":{}},"updateMatrix":{"overriden_options":{}}},"maxInputsCount":5,"inputs":[{"index":0,"node":"onEventTick1","output":"trigger"},null,{"index":2,"node":"floatToVec3_1","output":"vec3"}]},"triggerFilter1":{"type":"triggerFilter","params":{"condition":{"overriden_options":{}}},"maxInputsCount":2,"inputs":[{"index":0,"node":"onEventObjectHovered1","output":"trigger"},{"index":1,"node":"onEventObjectHovered1","output":"hovered"}]},"setObjectAttribute2":{"type":"setObjectAttribute","params":{"trigger":{"overriden_options":{}},"attribName":"rotationsCount","lerp":{"type":"float","default_value":1,"options":{"spare":true,"editable":true}},"val":{"type":"float","default_value":0,"options":{"spare":true,"editable":false}}},"maxInputsCount":4,"inputs":[{"index":0,"node":"triggerFilter1","output":"trigger"},null,null,{"index":3,"node":"add1","output":"sum"}],"connection_points":{"in":[{"name":"trigger","type":"trigger","isArray":false},{"name":"Object3D","type":"Object3D","isArray":false},{"name":"lerp","type":"float","isArray":false},{"name":"val","type":"float","isArray":false}],"out":[]}}},"inputs":["attribCreate5"],"flags":{"display":true}},"attribCreate1":{"type":"attribCreate","params":{"name":"scale","size":3,"value3":[1,"@height",1]},"inputs":["attribRemap1"]},"attribCreate2":{"type":"attribCreate","params":{"name":"height","value1":"@ptnum / (pointsCount(0)-1)"},"inputs":["transform2"]},"attribCreate3":{"type":"attribCreate","params":{"class":1,"name":"id","value1":"@ptnum"},"inputs":["attribPromote1"]},"attribCreate4":{"type":"attribCreate","params":{"class":1,"name":"id2","value1":"@id*2"},"inputs":["attribCreate3"]},"attribCreate5":{"type":"attribCreate","params":{"class":1,"name":"rotationsCount"},"inputs":["transform1"]},"attribPromote1":{"type":"attribPromote","params":{"classFrom":1,"classTo":0,"name":"color"},"inputs":["copy1"]},"attribRemap1":{"type":"attribRemap","params":{"name":"height","ramp":{"interpolation":"cubic","points":[{"position":0,"value":0.13749999999999996},{"position":0.1974589730015882,"value":0.4888671874999999},{"position":0.48205399682371625,"value":0.8013671875},{"position":0.7993399339933993,"value":0.43886718750000003},{"position":1,"value":1}]}},"inputs":["attribCreate2"]},"audioNotes1":{"type":"audioNotes","params":{"startOctave":3},"inputs":["objectProperties1"]},"copy1":{"type":"copy","params":{"copyAttributes":true,"attributesToCopy":"color"},"inputs":["material1","palette2"]},"line1":{"type":"line","params":{"length":20,"pointsCount":"(ch(\"length\")+1)/0.8","direction":[1,0,0]}},"material1":{"type":"material","params":{"material":"../MAT/meshStandard1"},"inputs":["roundedBox1"]},"objectProperties1":{"type":"objectProperties","params":{"tname":true,"name":"mainBox_`@id`"},"inputs":["attribCreate3"]},"palette2":{"type":"palette","params":{"colorsCount":4,"color1":{"raw_input":[0.8274509803921568,0.4117647058823529,0.24313725490196078],"overriden_options":{"0":"c","1":"o","2":"n","3":"v","4":"e","5":"r","6":"s","7":"i","8":"o","9":"n"}},"color2":{"raw_input":[0.5019607843137255,0.20784313725490197,0.1568627450980392],"overriden_options":{"0":"c","1":"o","2":"n","3":"v","4":"e","5":"r","6":"s","7":"i","8":"o","9":"n"}},"color3":{"raw_input":[0.9450980392156862,0.6941176470588235,0.33725490196078434],"overriden_options":{"0":"c","1":"o","2":"n","3":"v","4":"e","5":"r","6":"s","7":"i","8":"o","9":"n"}},"color4":{"raw_input":[0.5647058823529412,0.6549019607843137,0.596078431372549],"overriden_options":{"0":"c","1":"o","2":"n","3":"v","4":"e","5":"r","6":"s","7":"i","8":"o","9":"n"}},"color5":[0.2549019607843137,0.5529411764705883,0.803921568627451]},"inputs":["attribCreate1"]},"roundedBox1":{"type":"roundedBox","params":{"size":0.77,"sizes":[1,8,1],"divisions":6,"bevel":0.16}},"transform1":{"type":"transform","params":{"applyOn":1,"objectMode":1},"inputs":["audioNotes1"]},"transform2":{"type":"transform","params":{"t":["-$CEX",5.212417308354685,0]},"inputs":["line1"]}},"params":{"r":[0,38.15006823740499,0]},"flags":{"display":true}},"rotatingSpheres":{"type":"geo","nodes":{"MAT":{"type":"materialsNetwork","nodes":{"meshPhysicalBuilder1":{"type":"meshPhysicalBuilder","nodes":{"abs1":{"type":"abs","params":{"in":{"type":"float","default_value":0,"options":{"spare":true,"editable":false}}},"inputs":[{"index":0,"node":"noise1","output":"noise"}],"connection_points":{"in":[{"name":"in","type":"float"}],"out":[{"name":"val","type":"float"}]}},"add1":{"type":"add","params":{"add0":{"type":"float","default_value":0,"options":{"spare":true,"editable":false}},"add1":{"type":"float","default_value":0,"options":{"spare":true,"editable":false}},"add2":{"type":"float","default_value":0,"options":{"spare":true,"editable":true}}},"maxInputsCount":3,"inputs":[{"index":0,"node":"constant1","output":"val"},{"index":1,"node":"noise1","output":"noise"}],"connection_points":{"in":[{"name":"add0","type":"float"},{"name":"add1","type":"float"},{"name":"add2","type":"float"}],"out":[{"name":"sum","type":"float"}]}},"attribute1":{"type":"attribute","params":{"name":"instancePosition","type":2},"connection_points":{"in":[],"out":[{"name":"val","type":"vec3"}]}},"attribute2":{"type":"attribute","params":{"name":"id"},"connection_points":{"in":[],"out":[{"name":"val","type":"float"}]}},"constant1":{"type":"constant","params":{"float":1},"connection_points":{"in":[],"out":[{"name":"val","type":"float"}]}},"floatToVec2_1":{"type":"floatToVec2","params":{"x":{"overriden_options":{}},"y":{"overriden_options":{}}},"inputs":[{"index":0,"node":"round1","output":"val"}]},"globals1":{"type":"globals"},"instanceTransform1":{"type":"instanceTransform","params":{"position":{"overriden_options":{}},"normal":{"overriden_options":{}},"instancePosition":{"overriden_options":{}},"instanceOrientation":{"overriden_options":{}},"instanceScale":{"overriden_options":{}}},"inputs":[null,null,{"index":2,"node":"mult1","output":"product"}]},"length1":{"type":"length","params":{"x":{"type":"vector3","default_value":[0,0,0],"options":{"spare":true,"editable":false}}},"inputs":[{"index":0,"node":"attribute1","output":"val"}],"connection_points":{"in":[{"name":"x","type":"vec3"}],"out":[{"name":"val","type":"float"}]}},"mult1":{"type":"mult","params":{"mult0":{"type":"float","default_value":1,"options":{"spare":true,"editable":false}},"mult1":{"type":"vector3","default_value":[1,1,1],"options":{"spare":true,"editable":false}}},"inputs":[{"index":0,"node":"length1","output":"val"},{"index":1,"node":"rotate1","output":"val"}],"connection_points":{"in":[{"name":"mult0","type":"float"},{"name":"mult1","type":"vec3"}],"out":[{"name":"product","type":"vec3"}]}},"multAdd1":{"type":"multAdd","params":{"value":{"type":"float","default_value":0,"options":{"spare":true,"editable":false}},"preAdd":{"type":"float","default_value":0,"options":{"spare":true,"editable":true}},"mult":{"type":"float","default_value":1,"options":{"spare":true,"editable":true},"raw_input":0.51},"postAdd":{"type":"float","default_value":0,"options":{"spare":true,"editable":true}}},"inputs":[{"index":0,"node":"globals1","output":"time"}],"connection_points":{"in":[{"name":"value","type":"float"},{"name":"preAdd","type":"float"},{"name":"mult","type":"float"},{"name":"postAdd","type":"float"}],"out":[{"name":"val","type":"float"}]}},"noise1":{"type":"noise","params":{"outputType":1,"amp":{"type":"float","default_value":1,"options":{"spare":true,"editable":true},"raw_input":0.45},"position":{"type":"vector3","default_value":[0,0,0],"options":{"spare":true,"editable":false}},"freq":{"type":"vector3","default_value":[1,1,1],"options":{"spare":true,"editable":true},"raw_input":[100,100,100]},"offset":{"type":"vector3","default_value":[0,0,0],"options":{"spare":true,"editable":true}}},"maxInputsCount":4,"inputs":[null,{"index":1,"node":"globals1","output":"position"}],"connection_points":{"in":[{"name":"amp","type":"float"},{"name":"position","type":"vec3"},{"name":"freq","type":"vec3"},{"name":"offset","type":"vec3"}],"out":[{"name":"noise","type":"float"}]}},"normalize1":{"type":"normalize","params":{"in":{"type":"vector3","default_value":[0,0,0],"options":{"spare":true,"editable":false}}},"inputs":[{"index":0,"node":"attribute1","output":"val"}],"connection_points":{"in":[{"name":"in","type":"vec3"}],"out":[{"name":"normalized","type":"vec3"}]}},"output1":{"type":"output","inputs":[{"index":0,"node":"instanceTransform1","output":"position"},{"index":1,"node":"instanceTransform1","output":"normal"},null,null,null,null,{"index":6,"node":"random1","output":"rand"},null,null,null,{"index":10,"node":"add1","output":"sum"}]},"random1":{"type":"random","params":{"seed":{"overriden_options":{}}},"inputs":[{"index":0,"node":"floatToVec2_1","output":"vec2"}]},"rotate1":{"type":"rotate","params":{"vector":{"type":"vector3","default_value":[0,0,1],"options":{"spare":true,"editable":false}},"axis":{"type":"vector3","default_value":[0,1,0],"options":{"spare":true,"editable":true},"raw_input":[0,0,1]},"angle":{"type":"float","default_value":0,"options":{"spare":true,"editable":false}}},"maxInputsCount":3,"inputs":[{"index":0,"node":"normalize1","output":"normalized"},null,{"index":2,"node":"multAdd1","output":"val"}],"connection_points":{"in":[{"name":"vector","type":"vec3"},{"name":"axis","type":"vec3"},{"name":"angle","type":"float"}],"out":[{"name":"val","type":"vec3"}]}},"round1":{"type":"round","params":{"in":{"type":"float","default_value":0,"options":{"spare":true,"editable":false}}},"inputs":[{"index":0,"node":"attribute2","output":"val"}],"connection_points":{"in":[{"name":"in","type":"float"}],"out":[{"name":"val","type":"float"}]}}},"params":{"useEnvMap":true,"envMap":"../../../COP/envMap","envMapIntensity":1.5,"metalness":0.06,"clearcoat":1,"clearcoatRoughness":0.01,"transmission":1,"ior":1.679983,"thickness":0.7,"attenuationDistance":2.7,"attenuationColor":[0.023529411764705882,0.07450980392156863,0.17647058823529413]},"persisted_config":{"material":{"metadata":{"version":4.5,"type":"Material","generator":"Material.toJSON"},"uuid":"/rotatingSpheres/MAT/meshPhysicalBuilder1-main","type":"MeshPhysicalMaterial","name":"/rotatingSpheres/MAT/meshPhysicalBuilder1","color":16777215,"roughness":1,"metalness":0.06,"sheen":0,"sheenColor":0,"sheenRoughness":1,"emissive":0,"specularIntensity":1,"specularColor":16777215,"clearcoat":1,"clearcoatRoughness":0.01,"iridescence":0,"iridescenceIOR":1.3,"iridescenceThicknessRange":[100,400],"envMapIntensity":1.5,"reflectivity":0.6343165236495905,"transmission":1,"thickness":0.7,"attenuationDistance":2.7,"attenuationColor":398125,"depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680,"fog":false},"onBeforeCompileDataJSONWithoutShaders":{"paramConfigs":[],"timeDependent":true,"resolutionDependent":false},"customMaterials":{"customDepthMaterial":{"material":{"metadata":{"version":4.5,"type":"Material","generator":"Material.toJSON"},"uuid":"/rotatingSpheres/MAT/meshPhysicalBuilder1-customDepthMaterial","type":"MeshDepthMaterial","name":"customDepthMaterial","depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680,"depthPacking":3201},"onBeforeCompileDataJSONWithoutShaders":{"paramConfigs":[],"timeDependent":true,"resolutionDependent":false}},"customDistanceMaterial":{"material":{"metadata":{"version":4.5,"type":"Material","generator":"Material.toJSON"},"uuid":"/rotatingSpheres/MAT/meshPhysicalBuilder1-customDistanceMaterial","type":"MeshDistanceMaterial","name":"customDistanceMaterial","depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680},"onBeforeCompileDataJSONWithoutShaders":{"paramConfigs":[],"timeDependent":true,"resolutionDependent":false}},"customDepthDOFMaterial":{"material":{"metadata":{"version":4.5,"type":"Material","generator":"Material.toJSON"},"uuid":"/rotatingSpheres/MAT/meshPhysicalBuilder1-customDepthDOFMaterial","type":"MeshDepthMaterial","name":"customDepthDOFMaterial","depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680,"depthPacking":3200},"onBeforeCompileDataJSONWithoutShaders":{"paramConfigs":[],"timeDependent":true,"resolutionDependent":false}}}}}}},"instance1":{"type":"instance","params":{"attributesToCopy":"instance* id","material":"../MAT/meshPhysicalBuilder1"},"inputs":["sphere1","scatter1"],"flags":{"display":true}},"scatter1":{"type":"scatter","params":{"pointsCount":10,"seed":13},"inputs":["tube1"]},"sphere1":{"type":"sphere"},"transform1":{"type":"transform"},"tube1":{"type":"tube","params":{"radiusTop":4.8,"radiusBottom":4.5,"height":22.900000000000002}}},"inputs":["null2"],"flags":{"display":true}},"perspectiveCamera_MAIN":{"type":"perspectiveCamera","nodes":{"events1":{"type":"eventsNetwork","nodes":{"cameraOrbitControls1":{"type":"cameraOrbitControls","params":{"allowPan":false,"minDistance":16,"maxDistance":22,"limitAzimuthAngle":true,"azimuthAngleRange":["-0.4*$PI","0.4*$PI"],"polarAngleRange":[0,"$PI*0.5"],"target":[-1.7511417564003886,4.8056149140646625,2.228021894132138]}}}},"renderersNetwork1":{"type":"renderersNetwork","nodes":{"WebGLRenderer1":{"type":"WebGLRenderer","params":{"alpha":false,"toneMapping":0}}}}},"params":{"t":[4.645050942978928,11.201242947142884,18.551025336113412],"r":[-21.396083605161095,20.044262726375518,7.648697907782715],"controls":"./events1/cameraOrbitControls1","setRenderer":true,"renderer":"renderersNetwork1/WebGLRenderer1"},"flags":{"display":true}},"perspectiveCamera_DEBUG":{"type":"perspectiveCamera","nodes":{"events1":{"type":"eventsNetwork","nodes":{"cameraOrbitControls2":{"type":"cameraOrbitControls","params":{"target":[-0.35568100073133685,3.9096117890283693,-1.531413882739077]}}}}},"params":{"t":[1.0049354542845284,9.022002997743003,18.177143989703644],"r":[-14.541987088239498,3.8231157746708253,0.990879998730258],"controls":"events1/cameraOrbitControls2","setRenderer":true,"renderer":"../perspectiveCamera_MAIN/renderersNetwork1/WebGLRenderer1"},"flags":{"display":true}},"null2":{"type":"null","params":{"t":[0,5.312613522707743,0],"r":[0,-49.365682806890725,0]},"flags":{"display":false}}},"params":{"mainCameraPath":"/perspectiveCamera_MAIN","useFog":1,"fogColor":[0,0,0],"fogDensity":0.02,"displayAudioIcon":1}},"ui":{"nodes":{"hemisphereLight1":{"pos":[100,350]},"spotLight1":{"pos":[250,450]},"COP":{"pos":[-350,350],"nodes":{"envMap":{"pos":[50,200]},"imageEnv":{"pos":[50,100]},"imageUv":{"pos":[-100,100]}}},"set":{"pos":[-350,-250],"nodes":{"MAT":{"pos":[-50,350],"nodes":{"meshStandard1":{"pos":[0,200]}}},"circle1":{"pos":[250,-650]},"material1":{"pos":[250,450]},"skin1":{"pos":[250,200]},"transform1":{"pos":[400,0]},"transform2":{"pos":[250,-550]},"transform3":{"pos":[250,-450]},"transform4":{"pos":[250,-300]},"transform5":{"pos":[250,-200]},"transform6":{"pos":[150,0]},"transform7":{"pos":[250,550]},"transform8":{"pos":[250,650]},"transform9":{"pos":[250,300]}}},"polarTransform1":{"pos":[250,250]},"gridHelper":{"pos":[-350,-350],"nodes":{"plane1":{"pos":[50,-150]},"planeHelper1":{"pos":[200,-100]}}},"spotLight2":{"pos":[450,450]},"polarTransform2":{"pos":[450,250]},"null1":{"pos":[250,150]},"contactShadow1":{"pos":[200,-50]},"positionalAudio1":{"pos":[-350,-50],"nodes":{"OUT":{"pos":[100,150]},"Synth1":{"pos":[300,-400]},"chorus1":{"pos":[350,-200]},"chorus2":{"pos":[500,-100]},"envelope1":{"pos":[0,-650]},"monoSynth1":{"pos":[0,-450]},"pitchShift1":{"pos":[500,-200]},"playInstrument1":{"pos":[100,300]},"polySynth1":{"pos":[550,-300]},"reverb1":{"pos":[-50,-150]},"reverb2":{"pos":[150,-200]},"switch1":{"pos":[-250,-300]},"switch2":{"pos":[50,50]},"volume1":{"pos":[-50,-50]}}},"audioListener1":{"pos":[-500,450]},"musicBoxes":{"pos":[-350,-150],"nodes":{"ANIM":{"pos":[-400,300],"nodes":{"PLAY":{"pos":[0,900]},"PLAY1":{"pos":[550,900]},"RESET":{"pos":[-300,700]},"RESET1":{"pos":[250,700]},"duration1":{"pos":[450,-200]},"duration2":{"pos":[600,-150]},"duration3":{"pos":[800,-200]},"duration5":{"pos":[0,0]},"easing1":{"pos":[0,100]},"easing2":{"pos":[600,-50]},"easing3":{"pos":[450,-50]},"easing4":{"pos":[800,-50]},"operation1":{"pos":[0,700]},"operation2":{"pos":[550,700]},"position1":{"pos":[0,600]},"position2":{"pos":[-300,600]},"position3":{"pos":[650,600]},"position4":{"pos":[250,600]},"propertyName1":{"pos":[0,400]},"propertyName2":{"pos":[550,400]},"propertyValue1":{"pos":[0,500]},"propertyValue2":{"pos":[-300,500]},"propertyValue3":{"pos":[550,500]},"propertyValue4":{"pos":[250,500]},"switch1":{"pos":[550,150]},"target1":{"pos":[0,300]},"target2":{"pos":[550,300]}}},"EVENTS":{"pos":[-400,400],"nodes":{"animation2":{"pos":[150,500]},"audio1":{"pos":[150,700]},"intersectData_ID":{"pos":[-150,150]},"intersectData_NOTE":{"pos":[-150,250]},"mouse1":{"pos":[-600,350]},"nodeCook1":{"pos":[-450,550]},"param4":{"pos":[-150,550]},"raycast1":{"pos":[-300,400]},"scene1":{"pos":[-450,300]},"setParam1":{"pos":[0,550]},"viewer1":{"pos":[-50,350]}}},"MAT":{"pos":[-400,200],"nodes":{"meshStandard1":{"pos":[-300,500]}}},"actor1":{"pos":[-100,1400],"nodes":{"add1":{"pos":[200,-200]},"floatToVec3_1":{"pos":[300,100]},"getObjectAttribute1":{"pos":[-50,-200]},"getObjectAttribute2":{"pos":[200,-550]},"mult1":{"pos":[200,100]},"onEventObjectHovered1":{"pos":[0,-400]},"onEventTick1":{"pos":[300,-50]},"playInstrumentNote1":{"pos":[450,-500]},"setObjectRotation1":{"pos":[550,0],"comment":"try change change the lerp parameter. The smaller the value, the slower the objects will rotate when hovering the mouse over them (but make sure to play the scene first)"},"triggerFilter1":{"pos":[200,-400]},"setObjectAttribute2":{"pos":[450,-350]}}},"attribCreate1":{"pos":[100,200]},"attribCreate2":{"pos":[100,-150]},"attribCreate3":{"pos":[-100,750]},"attribCreate4":{"pos":[50,850]},"attribCreate5":{"pos":[-100,1250]},"attribPromote1":{"pos":[-100,600]},"attribRemap1":{"pos":[100,50]},"audioNotes1":{"pos":[-100,1000]},"copy1":{"pos":[-100,500]},"line1":{"pos":[100,-400]},"material1":{"pos":[-100,300]},"objectProperties1":{"pos":[-100,900]},"palette2":{"pos":[100,300]},"roundedBox1":{"pos":[-100,-200]},"transform1":{"pos":[-100,1150]},"transform2":{"pos":[100,-300]}}},"rotatingSpheres":{"pos":[-150,-250],"nodes":{"MAT":{"pos":[-350,400],"nodes":{"meshPhysicalBuilder1":{"pos":[-150,250],"nodes":{"abs1":{"pos":[0,300]},"add1":{"pos":[100,200]},"attribute1":{"pos":[-500,-100]},"attribute2":{"pos":[-150,500]},"constant1":{"pos":[-50,200]},"floatToVec2_1":{"pos":[50,500]},"globals1":{"pos":[-600,100]},"instanceTransform1":{"pos":[50,0]},"length1":{"pos":[-300,-100]},"mult1":{"pos":[-50,-100]},"multAdd1":{"pos":[-450,300]},"noise1":{"pos":[-100,300]},"normalize1":{"pos":[-350,50]},"output1":{"pos":[300,0]},"random1":{"pos":[150,500]},"rotate1":{"pos":[-200,50]},"round1":{"pos":[-50,500]}}}}},"instance1":{"pos":[-50,450]},"scatter1":{"pos":[50,250]},"sphere1":{"pos":[-150,250]},"transform1":{"pos":[-150,0]},"tube1":{"pos":[50,-100]}}},"perspectiveCamera_MAIN":{"pos":[-500,250],"nodes":{"events1":{"pos":[-200,50],"nodes":{"cameraOrbitControls1":{"pos":[150,50]}}},"renderersNetwork1":{"pos":[-200,150],"nodes":{"WebGLRenderer1":{"pos":[-200,150]}}}}},"perspectiveCamera_DEBUG":{"pos":[-500,100],"nodes":{"events1":{"pos":[-200,50],"nodes":{"cameraOrbitControls2":{"pos":[-100,200]}}}}},"null2":{"pos":[-150,-350]}}},"shaders":{"/rotatingSpheres/MAT/meshPhysicalBuilder1":{"vertex":"#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n\tvarying vec3 vWorldPosition;\n#endif\n#include <common>\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/rotate1\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n\n\n\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nuniform float time;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nvarying vec3 v_POLY_globals1_position;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nvarying float v_POLY_attribute_id;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute1\nattribute vec3 instancePosition;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nattribute float id;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/instanceTransform1\nattribute vec4 instanceOrientation;\nattribute vec3 instanceScale;\n\n\n\n\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\n\n\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute1\n\tvec3 v_POLY_attribute1_val = instancePosition;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\n\tv_POLY_globals1_position = vec3(position);\n\tfloat v_POLY_globals1_time = time;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\n\tv_POLY_attribute_id = float(id);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/length1\n\tfloat v_POLY_length1_val = length(v_POLY_attribute1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/normalize1\n\tvec3 v_POLY_normalize1_normalized = normalize(v_POLY_attribute1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/multAdd1\n\tfloat v_POLY_multAdd1_val = (0.51*(v_POLY_globals1_time + 0.0)) + 0.0;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/rotate1\n\tvec3 v_POLY_rotate1_val = rotateWithAxisAngle(v_POLY_normalize1_normalized, vec3(0.0, 0.0, 1.0), v_POLY_multAdd1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/mult1\n\tvec3 v_POLY_mult1_product = (v_POLY_length1_val * v_POLY_rotate1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/instanceTransform1\n\tvec3 v_POLY_instanceTransform1_position = vec3(position);\n\tv_POLY_instanceTransform1_position *= instanceScale;\n\tv_POLY_instanceTransform1_position = rotateWithQuat( v_POLY_instanceTransform1_position, instanceOrientation );\n\tv_POLY_instanceTransform1_position += v_POLY_mult1_product;\n\tvec3 v_POLY_instanceTransform1_normal = vec3(normal);\n\tv_POLY_instanceTransform1_normal = rotateWithQuat( v_POLY_instanceTransform1_normal, instanceOrientation );\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/output1\n\tvec3 transformed = v_POLY_instanceTransform1_position;\n\tvec3 objectNormal = v_POLY_instanceTransform1_normal;\n\t#ifdef USE_TANGENT\n\t\tvec3 objectTangent = vec3( tangent.xyz );\n\t#endif\n\n\n\n\t#include <morphcolor_vertex>\n// removed:\n//\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n// removed:\n//\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n#ifdef USE_TRANSMISSION\n\tvWorldPosition = worldPosition.xyz;\n#endif\n}","fragment":"#define STANDARD\n#ifdef PHYSICAL\n\t#define IOR\n\t#define SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n\tuniform float ior;\n#endif\n#ifdef SPECULAR\n\tuniform float specularIntensity;\n\tuniform vec3 specularColor;\n\t#ifdef USE_SPECULARINTENSITYMAP\n\t\tuniform sampler2D specularIntensityMap;\n\t#endif\n\t#ifdef USE_SPECULARCOLORMAP\n\t\tuniform sampler2D specularColorMap;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_IRIDESCENCE\n\tuniform float iridescence;\n\tuniform float iridescenceIOR;\n\tuniform float iridescenceThicknessMinimum;\n\tuniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheenColor;\n\tuniform float sheenRoughness;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tuniform sampler2D sheenColorMap;\n\t#endif\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tuniform sampler2D sheenRoughnessMap;\n\t#endif\n#endif\nvarying vec3 vViewPosition;\n#include <common>\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/noise1\n// Modulo 289 without a division (only multiplications)\nfloat mod289(float x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec2 mod289(vec2 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec3 mod289(vec3 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec4 mod289(vec4 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n// Modulo 7 without a division\nvec3 mod7(vec3 x) {\n return x - floor(x * (1.0 / 7.0)) * 7.0;\n}\n\n// Permutation polynomial: (34x^2 + x) mod 289\nfloat permute(float x) {\n return mod289(((x*34.0)+1.0)*x);\n}\nvec3 permute(vec3 x) {\n return mod289((34.0 * x + 1.0) * x);\n}\nvec4 permute(vec4 x) {\n return mod289(((x*34.0)+1.0)*x);\n}\n\nfloat taylorInvSqrt(float r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\nvec4 taylorInvSqrt(vec4 r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\n\nvec2 fade(vec2 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\nvec3 fade(vec3 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\nvec4 fade(vec4 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\n//\n// Description : Array and textureless GLSL 2D/3D/4D simplex \n// noise functions.\n// Author : Ian McEwan, Ashima Arts.\n// Maintainer : stegu\n// Lastmod : 20110822 (ijm)\n// License : Copyright (C) 2011 Ashima Arts. All rights reserved.\n// Distributed under the MIT License. See LICENSE file.\n// https://github.com/ashima/webgl-noise\n// https://github.com/stegu/webgl-noise\n// \n\n\n\nfloat snoise(vec3 v)\n { \n const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\n// First corner\n vec3 i = floor(v + dot(v, C.yyy) );\n vec3 x0 = v - i + dot(i, C.xxx) ;\n\n// Other corners\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min( g.xyz, l.zxy );\n vec3 i2 = max( g.xyz, l.zxy );\n\n // x0 = x0 - 0.0 + 0.0 * C.xxx;\n // x1 = x0 - i1 + 1.0 * C.xxx;\n // x2 = x0 - i2 + 2.0 * C.xxx;\n // x3 = x0 - 1.0 + 3.0 * C.xxx;\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y\n vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y\n\n// Permutations\n i = mod289(i); \n vec4 p = permute( permute( permute( \n i.z + vec4(0.0, i1.z, i2.z, 1.0 ))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) \n + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));\n\n// Gradients: 7x7 points over a square, mapped onto an octahedron.\n// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)\n float n_ = 0.142857142857; // 1.0/7.0\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)\n\n vec4 x = x_ *ns.x + ns.yyyy;\n vec4 y = y_ *ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n\n vec4 b0 = vec4( x.xy, y.xy );\n vec4 b1 = vec4( x.zw, y.zw );\n\n //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;\n //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;\n vec4 s0 = floor(b0)*2.0 + 1.0;\n vec4 s1 = floor(b1)*2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;\n\n vec3 p0 = vec3(a0.xy,h.x);\n vec3 p1 = vec3(a0.zw,h.y);\n vec3 p2 = vec3(a1.xy,h.z);\n vec3 p3 = vec3(a1.zw,h.w);\n\n//Normalise gradients\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n// Mix final noise value\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), \n dot(p2,x2), dot(p3,x3) ) );\n }\n\n\nfloat fbm_snoise_rotatingSpheres_MAT_meshPhysicalBuilder1_noise1(in vec3 st) {\n\tfloat value = 0.0;\n\tfloat amplitude = 1.0;\n\tfor (int i = 0; i < 3; i++) {\n\t\tvalue += amplitude * snoise(st);\n\t\tst *= 2.0;\n\t\tamplitude *= 0.5;\n\t}\n\treturn value;\n}\n\n\n\n\n\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nuniform float time;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nvarying vec3 v_POLY_globals1_position;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nvarying float v_POLY_attribute_id;\n\n\n\n\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <bsdfs>\n#include <iridescence_fragment>\n#include <cube_uv_reflection_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_physical_pars_fragment>\n#include <fog_pars_fragment>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_physical_pars_fragment>\n#include <transmission_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <clearcoat_pars_fragment>\n#include <iridescence_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nstruct SSSModel {\n\tbool isActive;\n\tvec3 color;\n\tfloat thickness;\n\tfloat power;\n\tfloat scale;\n\tfloat distortion;\n\tfloat ambient;\n\tfloat attenuation;\n};\n\nvoid RE_Direct_Scattering(\n\tconst in IncidentLight directLight,\n\tconst in GeometricContext geometry,\n\tconst in SSSModel sssModel,\n\tinout ReflectedLight reflectedLight\n\t){\n\tvec3 scatteringHalf = normalize(directLight.direction + (geometry.normal * sssModel.distortion));\n\tfloat scatteringDot = pow(saturate(dot(geometry.viewDir, -scatteringHalf)), sssModel.power) * sssModel.scale;\n\tvec3 scatteringIllu = (scatteringDot + sssModel.ambient) * (sssModel.color * (1.0-sssModel.thickness));\n\treflectedLight.directDiffuse += scatteringIllu * sssModel.attenuation * directLight.color;\n}\n\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\n\n\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\n\tfloat v_POLY_globals1_time = time;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\n\tfloat v_POLY_attribute2_val = v_POLY_attribute_id;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/constant1\n\tfloat v_POLY_constant1_val = 1.0;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/noise1\n\tfloat v_POLY_noise1_noise = 0.45*fbm_snoise_rotatingSpheres_MAT_meshPhysicalBuilder1_noise1((v_POLY_globals1_position*vec3(100.0, 100.0, 100.0))+vec3(0.0, 0.0, 0.0));\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/round1\n\tfloat v_POLY_round1_val = sign(v_POLY_attribute2_val)*floor(abs(v_POLY_attribute2_val)+0.5);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/add1\n\tfloat v_POLY_add1_sum = (v_POLY_constant1_val + v_POLY_noise1_noise + 0.0);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_round1_val, 0.0);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/random1\n\tfloat v_POLY_random1_rand = rand(v_POLY_floatToVec2_1_vec2);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/output1\n\tfloat POLY_metalness = 1.0;\n\tfloat POLY_roughness = v_POLY_random1_rand;\n\tvec3 POLY_emissive = vec3(1.0, 1.0, 1.0);\n\tSSSModel POLY_SSSModel = SSSModel(/*isActive*/false,/*color*/vec3(1.0, 1.0, 1.0), /*thickness*/0.1, /*power*/2.0, /*scale*/16.0, /*distortion*/0.1,/*ambient*/0.4,/*attenuation*/0.8 );\n\tfloat POLY_transmission = 1.0;\n\tfloat POLY_thickness = v_POLY_add1_sum;\n\n\n\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive * POLY_emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\tfloat roughnessFactor = roughness * POLY_roughness;\n\n#ifdef USE_ROUGHNESSMAP\n\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\n\t// reads channel G, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n\troughnessFactor *= texelRoughness.g;\n\n#endif\n\n\tfloat metalnessFactor = metalness * POLY_metalness;\n\n#ifdef USE_METALNESSMAP\n\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\n\t// reads channel B, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n\tmetalnessFactor *= texelMetalness.b;\n\n#endif\n\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <clearcoat_normal_fragment_begin>\n\t#include <clearcoat_normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_fragment_begin>\nif(POLY_SSSModel.isActive){\n\tRE_Direct_Scattering(directLight, geometry, POLY_SSSModel, reflectedLight);\n}\n\n\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n\tvec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\t\n#ifdef USE_TRANSMISSION\n\n\tmaterial.transmission = transmission;\n\tmaterial.transmissionAlpha = 1.0;\n\tmaterial.thickness = thickness;\n\tmaterial.attenuationDistance = attenuationDistance;\n\tmaterial.attenuationColor = attenuationColor;\n\n\t#ifdef USE_TRANSMISSIONMAP\n\n\t\tmaterial.transmission *= texture2D( transmissionMap, vUv ).r;\n\n\t#endif\n\n\t#ifdef USE_THICKNESSMAP\n\n\t\tmaterial.thickness *= texture2D( thicknessMap, vUv ).g;\n\n\t#endif\n\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\n\tvec4 transmission = getIBLVolumeRefraction(\n\t\tn, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, material.ior, material.thickness,\n\t\tmaterial.attenuationColor, material.attenuationDistance );\n\n\tmaterial.transmissionAlpha = mix( material.transmissionAlpha, transmission.a, material.transmission );\n\n\ttotalDiffuse = mix( totalDiffuse, transmission.rgb, material.transmission );\n\n#endif\n\n\tvec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n\t#ifdef USE_SHEEN\n\t\tfloat sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor );\n\t\toutgoingLight = outgoingLight * sheenEnergyComp + sheenSpecular;\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNVcc = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\tvec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n\t\toutgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + clearcoatSpecular * material.clearcoat;\n\t#endif\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}","customDepthMaterial.vertex":"#include <common>\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/rotate1\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n\n\n\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nuniform float time;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nvarying vec3 v_POLY_globals1_position;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nvarying float v_POLY_attribute_id;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute1\nattribute vec3 instancePosition;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nattribute float id;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/instanceTransform1\nattribute vec4 instanceOrientation;\nattribute vec3 instanceScale;\n\n\n\n\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n// removed:\n//\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n// removed:\n//\t#include <begin_vertex>\n\n\n\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute1\n\tvec3 v_POLY_attribute1_val = instancePosition;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\n\tv_POLY_globals1_position = vec3(position);\n\tfloat v_POLY_globals1_time = time;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\n\tv_POLY_attribute_id = float(id);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/length1\n\tfloat v_POLY_length1_val = length(v_POLY_attribute1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/normalize1\n\tvec3 v_POLY_normalize1_normalized = normalize(v_POLY_attribute1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/multAdd1\n\tfloat v_POLY_multAdd1_val = (0.51*(v_POLY_globals1_time + 0.0)) + 0.0;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/rotate1\n\tvec3 v_POLY_rotate1_val = rotateWithAxisAngle(v_POLY_normalize1_normalized, vec3(0.0, 0.0, 1.0), v_POLY_multAdd1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/mult1\n\tvec3 v_POLY_mult1_product = (v_POLY_length1_val * v_POLY_rotate1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/instanceTransform1\n\tvec3 v_POLY_instanceTransform1_position = vec3(position);\n\tv_POLY_instanceTransform1_position *= instanceScale;\n\tv_POLY_instanceTransform1_position = rotateWithQuat( v_POLY_instanceTransform1_position, instanceOrientation );\n\tv_POLY_instanceTransform1_position += v_POLY_mult1_product;\n\tvec3 v_POLY_instanceTransform1_normal = vec3(normal);\n\tv_POLY_instanceTransform1_normal = rotateWithQuat( v_POLY_instanceTransform1_normal, instanceOrientation );\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/output1\n\tvec3 transformed = v_POLY_instanceTransform1_position;\n\tvec3 objectNormal = v_POLY_instanceTransform1_normal;\n\t#ifdef USE_TANGENT\n\t\tvec3 objectTangent = vec3( tangent.xyz );\n\t#endif\n\n\n\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvHighPrecisionZW = gl_Position.zw;\n}","customDepthMaterial.fragment":"\n// INSERT DEFINES\n\n\n#if DEPTH_PACKING == 3200\n\n\tuniform float opacity;\n\n#endif\n\n#include <common>\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/noise1\n// Modulo 289 without a division (only multiplications)\nfloat mod289(float x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec2 mod289(vec2 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec3 mod289(vec3 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec4 mod289(vec4 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n// Modulo 7 without a division\nvec3 mod7(vec3 x) {\n return x - floor(x * (1.0 / 7.0)) * 7.0;\n}\n\n// Permutation polynomial: (34x^2 + x) mod 289\nfloat permute(float x) {\n return mod289(((x*34.0)+1.0)*x);\n}\nvec3 permute(vec3 x) {\n return mod289((34.0 * x + 1.0) * x);\n}\nvec4 permute(vec4 x) {\n return mod289(((x*34.0)+1.0)*x);\n}\n\nfloat taylorInvSqrt(float r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\nvec4 taylorInvSqrt(vec4 r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\n\nvec2 fade(vec2 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\nvec3 fade(vec3 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\nvec4 fade(vec4 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\n//\n// Description : Array and textureless GLSL 2D/3D/4D simplex \n// noise functions.\n// Author : Ian McEwan, Ashima Arts.\n// Maintainer : stegu\n// Lastmod : 20110822 (ijm)\n// License : Copyright (C) 2011 Ashima Arts. All rights reserved.\n// Distributed under the MIT License. See LICENSE file.\n// https://github.com/ashima/webgl-noise\n// https://github.com/stegu/webgl-noise\n// \n\n\n\nfloat snoise(vec3 v)\n { \n const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\n// First corner\n vec3 i = floor(v + dot(v, C.yyy) );\n vec3 x0 = v - i + dot(i, C.xxx) ;\n\n// Other corners\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min( g.xyz, l.zxy );\n vec3 i2 = max( g.xyz, l.zxy );\n\n // x0 = x0 - 0.0 + 0.0 * C.xxx;\n // x1 = x0 - i1 + 1.0 * C.xxx;\n // x2 = x0 - i2 + 2.0 * C.xxx;\n // x3 = x0 - 1.0 + 3.0 * C.xxx;\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y\n vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y\n\n// Permutations\n i = mod289(i); \n vec4 p = permute( permute( permute( \n i.z + vec4(0.0, i1.z, i2.z, 1.0 ))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) \n + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));\n\n// Gradients: 7x7 points over a square, mapped onto an octahedron.\n// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)\n float n_ = 0.142857142857; // 1.0/7.0\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)\n\n vec4 x = x_ *ns.x + ns.yyyy;\n vec4 y = y_ *ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n\n vec4 b0 = vec4( x.xy, y.xy );\n vec4 b1 = vec4( x.zw, y.zw );\n\n //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;\n //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;\n vec4 s0 = floor(b0)*2.0 + 1.0;\n vec4 s1 = floor(b1)*2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;\n\n vec3 p0 = vec3(a0.xy,h.x);\n vec3 p1 = vec3(a0.zw,h.y);\n vec3 p2 = vec3(a1.xy,h.z);\n vec3 p3 = vec3(a1.zw,h.w);\n\n//Normalise gradients\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n// Mix final noise value\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), \n dot(p2,x2), dot(p3,x3) ) );\n }\n\n\nfloat fbm_snoise_rotatingSpheres_MAT_meshPhysicalBuilder1_noise1(in vec3 st) {\n\tfloat value = 0.0;\n\tfloat amplitude = 1.0;\n\tfor (int i = 0; i < 3; i++) {\n\t\tvalue += amplitude * snoise(st);\n\t\tst *= 2.0;\n\t\tamplitude *= 0.5;\n\t}\n\treturn value;\n}\n\n\n\n\n\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nuniform float time;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nvarying vec3 v_POLY_globals1_position;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nvarying float v_POLY_attribute_id;\n\n\n\n\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\n\nvarying vec2 vHighPrecisionZW;\n\nstruct SSSModel {\n\tbool isActive;\n\tvec3 color;\n\tfloat thickness;\n\tfloat power;\n\tfloat scale;\n\tfloat distortion;\n\tfloat ambient;\n\tfloat attenuation;\n};\n\nvoid RE_Direct_Scattering(\n\tconst in IncidentLight directLight,\n\tconst in GeometricContext geometry,\n\tconst in SSSModel sssModel,\n\tinout ReflectedLight reflectedLight\n\t){\n\tvec3 scatteringHalf = normalize(directLight.direction + (geometry.normal * sssModel.distortion));\n\tfloat scatteringDot = pow(saturate(dot(geometry.viewDir, -scatteringHalf)), sssModel.power) * sssModel.scale;\n\tvec3 scatteringIllu = (scatteringDot + sssModel.ambient) * (sssModel.color * (1.0-sssModel.thickness));\n\treflectedLight.directDiffuse += scatteringIllu * sssModel.attenuation * directLight.color;\n}\n\nvoid main() {\n\n\t#include <clipping_planes_fragment>\n\n\tvec4 diffuseColor = vec4( 1.0 );\n\n\t#if DEPTH_PACKING == 3200\n\n\t\tdiffuseColor.a = opacity;\n\n\t#endif\n\n\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\n\n\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\n\tfloat v_POLY_globals1_time = time;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\n\tfloat v_POLY_attribute2_val = v_POLY_attribute_id;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/constant1\n\tfloat v_POLY_constant1_val = 1.0;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/noise1\n\tfloat v_POLY_noise1_noise = 0.45*fbm_snoise_rotatingSpheres_MAT_meshPhysicalBuilder1_noise1((v_POLY_globals1_position*vec3(100.0, 100.0, 100.0))+vec3(0.0, 0.0, 0.0));\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/round1\n\tfloat v_POLY_round1_val = sign(v_POLY_attribute2_val)*floor(abs(v_POLY_attribute2_val)+0.5);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/add1\n\tfloat v_POLY_add1_sum = (v_POLY_constant1_val + v_POLY_noise1_noise + 0.0);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_round1_val, 0.0);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/random1\n\tfloat v_POLY_random1_rand = rand(v_POLY_floatToVec2_1_vec2);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/output1\n\tfloat POLY_metalness = 1.0;\n\tfloat POLY_roughness = v_POLY_random1_rand;\n\tvec3 POLY_emissive = vec3(1.0, 1.0, 1.0);\n\tSSSModel POLY_SSSModel = SSSModel(/*isActive*/false,/*color*/vec3(1.0, 1.0, 1.0), /*thickness*/0.1, /*power*/2.0, /*scale*/16.0, /*distortion*/0.1,/*ambient*/0.4,/*attenuation*/0.8 );\n\tfloat POLY_transmission = 1.0;\n\tfloat POLY_thickness = v_POLY_add1_sum;\n\n\n\n\n\t// INSERT BODY\n\t// the new body lines should be added before the alphatest_fragment\n\t// so that alpha is set before (which is really how it would be set if the alphamap_fragment above was used by the material node parameters)\n\n\t#include <alphatest_fragment>\n\n\t#include <logdepthbuf_fragment>\n\n\n\t// Higher precision equivalent of gl_FragCoord.z. This assumes depthRange has been left to its default values.\n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\n\t#if DEPTH_PACKING == 3200\n\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), diffuseColor.a );\n\n\t#elif DEPTH_PACKING == 3201\n\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\n\t#endif\n\n}\n","customDistanceMaterial.vertex":"#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/rotate1\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n\n\n\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nuniform float time;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nvarying vec3 v_POLY_globals1_position;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nvarying float v_POLY_attribute_id;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute1\nattribute vec3 instancePosition;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nattribute float id;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/instanceTransform1\nattribute vec4 instanceOrientation;\nattribute vec3 instanceScale;\n\n\n\n\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n// removed:\n//\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n// removed:\n//\t#include <begin_vertex>\n\n\n\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute1\n\tvec3 v_POLY_attribute1_val = instancePosition;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\n\tv_POLY_globals1_position = vec3(position);\n\tfloat v_POLY_globals1_time = time;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\n\tv_POLY_attribute_id = float(id);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/length1\n\tfloat v_POLY_length1_val = length(v_POLY_attribute1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/normalize1\n\tvec3 v_POLY_normalize1_normalized = normalize(v_POLY_attribute1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/multAdd1\n\tfloat v_POLY_multAdd1_val = (0.51*(v_POLY_globals1_time + 0.0)) + 0.0;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/rotate1\n\tvec3 v_POLY_rotate1_val = rotateWithAxisAngle(v_POLY_normalize1_normalized, vec3(0.0, 0.0, 1.0), v_POLY_multAdd1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/mult1\n\tvec3 v_POLY_mult1_product = (v_POLY_length1_val * v_POLY_rotate1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/instanceTransform1\n\tvec3 v_POLY_instanceTransform1_position = vec3(position);\n\tv_POLY_instanceTransform1_position *= instanceScale;\n\tv_POLY_instanceTransform1_position = rotateWithQuat( v_POLY_instanceTransform1_position, instanceOrientation );\n\tv_POLY_instanceTransform1_position += v_POLY_mult1_product;\n\tvec3 v_POLY_instanceTransform1_normal = vec3(normal);\n\tv_POLY_instanceTransform1_normal = rotateWithQuat( v_POLY_instanceTransform1_normal, instanceOrientation );\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/output1\n\tvec3 transformed = v_POLY_instanceTransform1_position;\n\tvec3 objectNormal = v_POLY_instanceTransform1_normal;\n\t#ifdef USE_TANGENT\n\t\tvec3 objectTangent = vec3( tangent.xyz );\n\t#endif\n\n\n\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}","customDistanceMaterial.fragment":"\n// INSERT DEFINES\n\n#define DISTANCE\n\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n\n#include <common>\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/noise1\n// Modulo 289 without a division (only multiplications)\nfloat mod289(float x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec2 mod289(vec2 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec3 mod289(vec3 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec4 mod289(vec4 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n// Modulo 7 without a division\nvec3 mod7(vec3 x) {\n return x - floor(x * (1.0 / 7.0)) * 7.0;\n}\n\n// Permutation polynomial: (34x^2 + x) mod 289\nfloat permute(float x) {\n return mod289(((x*34.0)+1.0)*x);\n}\nvec3 permute(vec3 x) {\n return mod289((34.0 * x + 1.0) * x);\n}\nvec4 permute(vec4 x) {\n return mod289(((x*34.0)+1.0)*x);\n}\n\nfloat taylorInvSqrt(float r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\nvec4 taylorInvSqrt(vec4 r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\n\nvec2 fade(vec2 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\nvec3 fade(vec3 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\nvec4 fade(vec4 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\n//\n// Description : Array and textureless GLSL 2D/3D/4D simplex \n// noise functions.\n// Author : Ian McEwan, Ashima Arts.\n// Maintainer : stegu\n// Lastmod : 20110822 (ijm)\n// License : Copyright (C) 2011 Ashima Arts. All rights reserved.\n// Distributed under the MIT License. See LICENSE file.\n// https://github.com/ashima/webgl-noise\n// https://github.com/stegu/webgl-noise\n// \n\n\n\nfloat snoise(vec3 v)\n { \n const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\n// First corner\n vec3 i = floor(v + dot(v, C.yyy) );\n vec3 x0 = v - i + dot(i, C.xxx) ;\n\n// Other corners\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min( g.xyz, l.zxy );\n vec3 i2 = max( g.xyz, l.zxy );\n\n // x0 = x0 - 0.0 + 0.0 * C.xxx;\n // x1 = x0 - i1 + 1.0 * C.xxx;\n // x2 = x0 - i2 + 2.0 * C.xxx;\n // x3 = x0 - 1.0 + 3.0 * C.xxx;\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y\n vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y\n\n// Permutations\n i = mod289(i); \n vec4 p = permute( permute( permute( \n i.z + vec4(0.0, i1.z, i2.z, 1.0 ))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) \n + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));\n\n// Gradients: 7x7 points over a square, mapped onto an octahedron.\n// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)\n float n_ = 0.142857142857; // 1.0/7.0\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)\n\n vec4 x = x_ *ns.x + ns.yyyy;\n vec4 y = y_ *ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n\n vec4 b0 = vec4( x.xy, y.xy );\n vec4 b1 = vec4( x.zw, y.zw );\n\n //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;\n //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;\n vec4 s0 = floor(b0)*2.0 + 1.0;\n vec4 s1 = floor(b1)*2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;\n\n vec3 p0 = vec3(a0.xy,h.x);\n vec3 p1 = vec3(a0.zw,h.y);\n vec3 p2 = vec3(a1.xy,h.z);\n vec3 p3 = vec3(a1.zw,h.w);\n\n//Normalise gradients\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n// Mix final noise value\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), \n dot(p2,x2), dot(p3,x3) ) );\n }\n\n\nfloat fbm_snoise_rotatingSpheres_MAT_meshPhysicalBuilder1_noise1(in vec3 st) {\n\tfloat value = 0.0;\n\tfloat amplitude = 1.0;\n\tfor (int i = 0; i < 3; i++) {\n\t\tvalue += amplitude * snoise(st);\n\t\tst *= 2.0;\n\t\tamplitude *= 0.5;\n\t}\n\treturn value;\n}\n\n\n\n\n\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nuniform float time;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nvarying vec3 v_POLY_globals1_position;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nvarying float v_POLY_attribute_id;\n\n\n\n\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <clipping_planes_pars_fragment>\n\nstruct SSSModel {\n\tbool isActive;\n\tvec3 color;\n\tfloat thickness;\n\tfloat power;\n\tfloat scale;\n\tfloat distortion;\n\tfloat ambient;\n\tfloat attenuation;\n};\n\nvoid RE_Direct_Scattering(\n\tconst in IncidentLight directLight,\n\tconst in GeometricContext geometry,\n\tconst in SSSModel sssModel,\n\tinout ReflectedLight reflectedLight\n\t){\n\tvec3 scatteringHalf = normalize(directLight.direction + (geometry.normal * sssModel.distortion));\n\tfloat scatteringDot = pow(saturate(dot(geometry.viewDir, -scatteringHalf)), sssModel.power) * sssModel.scale;\n\tvec3 scatteringIllu = (scatteringDot + sssModel.ambient) * (sssModel.color * (1.0-sssModel.thickness));\n\treflectedLight.directDiffuse += scatteringIllu * sssModel.attenuation * directLight.color;\n}\n\nvoid main() {\n\n\t#include <clipping_planes_fragment>\n\n\tvec4 diffuseColor = vec4( 1.0 );\n\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\n\n\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\n\tfloat v_POLY_globals1_time = time;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\n\tfloat v_POLY_attribute2_val = v_POLY_attribute_id;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/constant1\n\tfloat v_POLY_constant1_val = 1.0;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/noise1\n\tfloat v_POLY_noise1_noise = 0.45*fbm_snoise_rotatingSpheres_MAT_meshPhysicalBuilder1_noise1((v_POLY_globals1_position*vec3(100.0, 100.0, 100.0))+vec3(0.0, 0.0, 0.0));\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/round1\n\tfloat v_POLY_round1_val = sign(v_POLY_attribute2_val)*floor(abs(v_POLY_attribute2_val)+0.5);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/add1\n\tfloat v_POLY_add1_sum = (v_POLY_constant1_val + v_POLY_noise1_noise + 0.0);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_round1_val, 0.0);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/random1\n\tfloat v_POLY_random1_rand = rand(v_POLY_floatToVec2_1_vec2);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/output1\n\tfloat POLY_metalness = 1.0;\n\tfloat POLY_roughness = v_POLY_random1_rand;\n\tvec3 POLY_emissive = vec3(1.0, 1.0, 1.0);\n\tSSSModel POLY_SSSModel = SSSModel(/*isActive*/false,/*color*/vec3(1.0, 1.0, 1.0), /*thickness*/0.1, /*power*/2.0, /*scale*/16.0, /*distortion*/0.1,/*ambient*/0.4,/*attenuation*/0.8 );\n\tfloat POLY_transmission = 1.0;\n\tfloat POLY_thickness = v_POLY_add1_sum;\n\n\n\n\n\t// INSERT BODY\n\n\t#include <alphatest_fragment>\n\n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist ); // clamp to [ 0, 1 ]\n\n\tgl_FragColor = packDepthToRGBA( dist );\n\n}\n","customDepthDOFMaterial.vertex":"#include <common>\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/rotate1\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n\n\n\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nuniform float time;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nvarying vec3 v_POLY_globals1_position;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nvarying float v_POLY_attribute_id;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute1\nattribute vec3 instancePosition;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nattribute float id;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/instanceTransform1\nattribute vec4 instanceOrientation;\nattribute vec3 instanceScale;\n\n\n\n\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n// removed:\n//\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n// removed:\n//\t#include <begin_vertex>\n\n\n\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute1\n\tvec3 v_POLY_attribute1_val = instancePosition;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\n\tv_POLY_globals1_position = vec3(position);\n\tfloat v_POLY_globals1_time = time;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\n\tv_POLY_attribute_id = float(id);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/length1\n\tfloat v_POLY_length1_val = length(v_POLY_attribute1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/normalize1\n\tvec3 v_POLY_normalize1_normalized = normalize(v_POLY_attribute1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/multAdd1\n\tfloat v_POLY_multAdd1_val = (0.51*(v_POLY_globals1_time + 0.0)) + 0.0;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/rotate1\n\tvec3 v_POLY_rotate1_val = rotateWithAxisAngle(v_POLY_normalize1_normalized, vec3(0.0, 0.0, 1.0), v_POLY_multAdd1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/mult1\n\tvec3 v_POLY_mult1_product = (v_POLY_length1_val * v_POLY_rotate1_val);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/instanceTransform1\n\tvec3 v_POLY_instanceTransform1_position = vec3(position);\n\tv_POLY_instanceTransform1_position *= instanceScale;\n\tv_POLY_instanceTransform1_position = rotateWithQuat( v_POLY_instanceTransform1_position, instanceOrientation );\n\tv_POLY_instanceTransform1_position += v_POLY_mult1_product;\n\tvec3 v_POLY_instanceTransform1_normal = vec3(normal);\n\tv_POLY_instanceTransform1_normal = rotateWithQuat( v_POLY_instanceTransform1_normal, instanceOrientation );\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/output1\n\tvec3 transformed = v_POLY_instanceTransform1_position;\n\tvec3 objectNormal = v_POLY_instanceTransform1_normal;\n\t#ifdef USE_TANGENT\n\t\tvec3 objectTangent = vec3( tangent.xyz );\n\t#endif\n\n\n\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvHighPrecisionZW = gl_Position.zw;\n}","customDepthDOFMaterial.fragment":"\n// INSERT DEFINES\n\n\n#if DEPTH_PACKING == 3200\n\n\tuniform float opacity;\n\n#endif\n\n#include <common>\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/noise1\n// Modulo 289 without a division (only multiplications)\nfloat mod289(float x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec2 mod289(vec2 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec3 mod289(vec3 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\nvec4 mod289(vec4 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n// Modulo 7 without a division\nvec3 mod7(vec3 x) {\n return x - floor(x * (1.0 / 7.0)) * 7.0;\n}\n\n// Permutation polynomial: (34x^2 + x) mod 289\nfloat permute(float x) {\n return mod289(((x*34.0)+1.0)*x);\n}\nvec3 permute(vec3 x) {\n return mod289((34.0 * x + 1.0) * x);\n}\nvec4 permute(vec4 x) {\n return mod289(((x*34.0)+1.0)*x);\n}\n\nfloat taylorInvSqrt(float r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\nvec4 taylorInvSqrt(vec4 r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\n\nvec2 fade(vec2 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\nvec3 fade(vec3 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\nvec4 fade(vec4 t) {\n return t*t*t*(t*(t*6.0-15.0)+10.0);\n}\n//\n// Description : Array and textureless GLSL 2D/3D/4D simplex \n// noise functions.\n// Author : Ian McEwan, Ashima Arts.\n// Maintainer : stegu\n// Lastmod : 20110822 (ijm)\n// License : Copyright (C) 2011 Ashima Arts. All rights reserved.\n// Distributed under the MIT License. See LICENSE file.\n// https://github.com/ashima/webgl-noise\n// https://github.com/stegu/webgl-noise\n// \n\n\n\nfloat snoise(vec3 v)\n { \n const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\n// First corner\n vec3 i = floor(v + dot(v, C.yyy) );\n vec3 x0 = v - i + dot(i, C.xxx) ;\n\n// Other corners\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min( g.xyz, l.zxy );\n vec3 i2 = max( g.xyz, l.zxy );\n\n // x0 = x0 - 0.0 + 0.0 * C.xxx;\n // x1 = x0 - i1 + 1.0 * C.xxx;\n // x2 = x0 - i2 + 2.0 * C.xxx;\n // x3 = x0 - 1.0 + 3.0 * C.xxx;\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y\n vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y\n\n// Permutations\n i = mod289(i); \n vec4 p = permute( permute( permute( \n i.z + vec4(0.0, i1.z, i2.z, 1.0 ))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) \n + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));\n\n// Gradients: 7x7 points over a square, mapped onto an octahedron.\n// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)\n float n_ = 0.142857142857; // 1.0/7.0\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)\n\n vec4 x = x_ *ns.x + ns.yyyy;\n vec4 y = y_ *ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n\n vec4 b0 = vec4( x.xy, y.xy );\n vec4 b1 = vec4( x.zw, y.zw );\n\n //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;\n //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;\n vec4 s0 = floor(b0)*2.0 + 1.0;\n vec4 s1 = floor(b1)*2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;\n\n vec3 p0 = vec3(a0.xy,h.x);\n vec3 p1 = vec3(a0.zw,h.y);\n vec3 p2 = vec3(a1.xy,h.z);\n vec3 p3 = vec3(a1.zw,h.w);\n\n//Normalise gradients\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n// Mix final noise value\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), \n dot(p2,x2), dot(p3,x3) ) );\n }\n\n\nfloat fbm_snoise_rotatingSpheres_MAT_meshPhysicalBuilder1_noise1(in vec3 st) {\n\tfloat value = 0.0;\n\tfloat amplitude = 1.0;\n\tfor (int i = 0; i < 3; i++) {\n\t\tvalue += amplitude * snoise(st);\n\t\tst *= 2.0;\n\t\tamplitude *= 0.5;\n\t}\n\treturn value;\n}\n\n\n\n\n\n\n\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nuniform float time;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\nvarying vec3 v_POLY_globals1_position;\n\n// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\nvarying float v_POLY_attribute_id;\n\n\n\n\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\n\nvarying vec2 vHighPrecisionZW;\n\nstruct SSSModel {\n\tbool isActive;\n\tvec3 color;\n\tfloat thickness;\n\tfloat power;\n\tfloat scale;\n\tfloat distortion;\n\tfloat ambient;\n\tfloat attenuation;\n};\n\nvoid RE_Direct_Scattering(\n\tconst in IncidentLight directLight,\n\tconst in GeometricContext geometry,\n\tconst in SSSModel sssModel,\n\tinout ReflectedLight reflectedLight\n\t){\n\tvec3 scatteringHalf = normalize(directLight.direction + (geometry.normal * sssModel.distortion));\n\tfloat scatteringDot = pow(saturate(dot(geometry.viewDir, -scatteringHalf)), sssModel.power) * sssModel.scale;\n\tvec3 scatteringIllu = (scatteringDot + sssModel.ambient) * (sssModel.color * (1.0-sssModel.thickness));\n\treflectedLight.directDiffuse += scatteringIllu * sssModel.attenuation * directLight.color;\n}\n\nvoid main() {\n\n\t#include <clipping_planes_fragment>\n\n\tvec4 diffuseColor = vec4( 1.0 );\n\n\t#if DEPTH_PACKING == 3200\n\n\t\tdiffuseColor.a = opacity;\n\n\t#endif\n\n\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\n\n\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/globals1\n\tfloat v_POLY_globals1_time = time;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/attribute2\n\tfloat v_POLY_attribute2_val = v_POLY_attribute_id;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/constant1\n\tfloat v_POLY_constant1_val = 1.0;\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/noise1\n\tfloat v_POLY_noise1_noise = 0.45*fbm_snoise_rotatingSpheres_MAT_meshPhysicalBuilder1_noise1((v_POLY_globals1_position*vec3(100.0, 100.0, 100.0))+vec3(0.0, 0.0, 0.0));\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/round1\n\tfloat v_POLY_round1_val = sign(v_POLY_attribute2_val)*floor(abs(v_POLY_attribute2_val)+0.5);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/add1\n\tfloat v_POLY_add1_sum = (v_POLY_constant1_val + v_POLY_noise1_noise + 0.0);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_round1_val, 0.0);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/random1\n\tfloat v_POLY_random1_rand = rand(v_POLY_floatToVec2_1_vec2);\n\t\n\t// /rotatingSpheres/MAT/meshPhysicalBuilder1/output1\n\tfloat POLY_metalness = 1.0;\n\tfloat POLY_roughness = v_POLY_random1_rand;\n\tvec3 POLY_emissive = vec3(1.0, 1.0, 1.0);\n\tSSSModel POLY_SSSModel = SSSModel(/*isActive*/false,/*color*/vec3(1.0, 1.0, 1.0), /*thickness*/0.1, /*power*/2.0, /*scale*/16.0, /*distortion*/0.1,/*ambient*/0.4,/*attenuation*/0.8 );\n\tfloat POLY_transmission = 1.0;\n\tfloat POLY_thickness = v_POLY_add1_sum;\n\n\n\n\n\t// INSERT BODY\n\t// the new body lines should be added before the alphatest_fragment\n\t// so that alpha is set before (which is really how it would be set if the alphamap_fragment above was used by the material node parameters)\n\n\t#include <alphatest_fragment>\n\n\t#include <logdepthbuf_fragment>\n\n\n\t// Higher precision equivalent of gl_FragCoord.z. This assumes depthRange has been left to its default values.\n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\n\t#if DEPTH_PACKING == 3200\n\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), diffuseColor.a );\n\n\t#elif DEPTH_PACKING == 3201\n\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\n\t#endif\n\n}\n"}}}
Code editor
{"multiple_panel":{"split_ratio":0.5,"split_panel0":{"split_ratio":0.5,"split_panel0":{"panelTypes":["viewer"],"currentPanelIndex":0,"panel_data":{"camera":"/perspectiveCamera_MAIN","linkIndex":1}},"split_panel1":{"panelTypes":["params"],"currentPanelIndex":0,"panel_data":{"active_folder":null,"linkIndex":1}},"split_mode":"vertical"},"split_panel1":{"panelTypes":["network","params","viewer"],"currentPanelIndex":0,"panel_data":{"camera":{"position":{"x":-357.56578639642885,"y":187.8362839979532},"zoom":0.7560000000000002},"history":{"2":{"position":{"x":255.6203866432337,"y":-135.39191564147626},"zoom":0.6290000000000001},"3":{"position":{"x":-48,"y":-22},"zoom":0.5},"6":{"position":{"x":11.339999999999996,"y":-96.49999999999999},"zoom":0.6172839506172841},"9":{"position":{"x":-32,"y":-88},"zoom":0.5},"102":{"position":{"x":25,"y":-150},"zoom":0.5690000000000001},"131":{"position":{"x":-59.04899999999998,"y":-65.1854},"zoom":0.8467543904215146},"298":{"position":{"x":-250.462,"y":5.910000000000017},"zoom":0.6172839506172841},"354":{"position":{"x":-56,"y":-370},"zoom":0.5},"358":{"position":{"x":-56,"y":-370},"zoom":0.5},"361":{"position":{"x":-163.35616438356158,"y":-607.8767123287671},"zoom":0.5840000000000001},"362":{"position":{"x":78.45786963434023,"y":-1085.0556438791732},"zoom":0.6290000000000001},"382":{"position":{"x":-8,"y":-102},"zoom":0.5},"1083":{"position":{"x":92,"y":-400},"zoom":0.5},"1090":{"position":{"x":92,"y":-400},"zoom":0.5},"1103":{"position":{"x":-357.56578639642885,"y":187.8362839979532},"zoom":0.7560000000000002}},"linkIndex":1}},"split_mode":"horizontal"},"currentNodes":["/musicBoxes/actor1","/","/","/","/","/","/","/"],"navigationHistory":{"nodePaths":{"1":["/","/COP","/","/musicBoxes","/musicBoxes/actor1"],"2":["/"],"3":["/"],"4":["/"],"5":["/"],"6":["/"],"7":["/"],"8":["/"]},"index":{"1":4,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0}},"fullscreenPanelId":null,"saveOptions":{"createExport":true,"skipExportSinceRemoteAssetsPresents":false,"compressJs":true,"createZip":true,"publishToIntegrations":false},"paramsModal":[]}
Used nodes
actor/add;actor/floatToVec3;actor/getObjectAttribute;actor/mult;actor/onObjectHover;actor/onTick;actor/playInstrumentNote;actor/setObjectAttribute;actor/setObjectRotation;actor/triggerFilter;anim/duration;anim/easing;anim/null;anim/operation;anim/position;anim/propertyName;anim/propertyValue;anim/switch;anim/target;audio/Synth;audio/chorus;audio/envelope;audio/monoSynth;audio/null;audio/pitchShift;audio/playInstrument;audio/polySynth;audio/reverb;audio/switch;audio/volume;cop/envMap;cop/image;cop/imageEXR;event/animation;event/audio;event/cameraOrbitControls;event/intersectData;event/mouse;event/nodeCook;event/param;event/raycast;event/scene;event/setParam;event/viewer;mat/meshPhysicalBuilder;mat/meshStandard;obj/audioListener;obj/contactShadow;obj/copNetwork;obj/geo;obj/hemisphereLight;obj/null;obj/perspectiveCamera;obj/polarTransform;obj/positionalAudio;obj/spotLight;rop/WebGLRenderer;sop/actor;sop/animationsNetwork;sop/attribCreate;sop/attribPromote;sop/attribRemap;sop/audioNotes;sop/circle;sop/copy;sop/eventsNetwork;sop/instance;sop/line;sop/material;sop/materialsNetwork;sop/objectProperties;sop/palette;sop/plane;sop/planeHelper;sop/renderersNetwork;sop/roundedBox;sop/scatter;sop/skin;sop/sphere;sop/transform;sop/tube
Used operations
Used modules
Used assemblers
GL_MESH_PHYSICAL
Used integrations
[]
Used assets
Nodes map
{"/hemisphereLight1":"obj/hemisphereLight","/spotLight1":"obj/spotLight","/COP":"obj/copNetwork","/COP/envMap":"cop/envMap","/COP/imageEnv":"cop/imageEXR","/COP/imageUv":"cop/image","/set":"obj/geo","/set/MAT":"sop/materialsNetwork","/set/MAT/meshStandard1":"mat/meshStandard","/set/circle1":"sop/circle","/set/material1":"sop/material","/set/skin1":"sop/skin","/set/transform1":"sop/transform","/set/transform2":"sop/transform","/set/transform3":"sop/transform","/set/transform4":"sop/transform","/set/transform5":"sop/transform","/set/transform6":"sop/transform","/set/transform7":"sop/transform","/set/transform8":"sop/transform","/set/transform9":"sop/transform","/polarTransform1":"obj/polarTransform","/gridHelper":"obj/geo","/gridHelper/plane1":"sop/plane","/gridHelper/planeHelper1":"sop/planeHelper","/spotLight2":"obj/spotLight","/polarTransform2":"obj/polarTransform","/null1":"obj/null","/contactShadow1":"obj/contactShadow","/positionalAudio1":"obj/positionalAudio","/positionalAudio1/OUT":"audio/null","/positionalAudio1/Synth1":"audio/Synth","/positionalAudio1/chorus1":"audio/chorus","/positionalAudio1/chorus2":"audio/chorus","/positionalAudio1/envelope1":"audio/envelope","/positionalAudio1/monoSynth1":"audio/monoSynth","/positionalAudio1/pitchShift1":"audio/pitchShift","/positionalAudio1/playInstrument1":"audio/playInstrument","/positionalAudio1/polySynth1":"audio/polySynth","/positionalAudio1/reverb1":"audio/reverb","/positionalAudio1/reverb2":"audio/reverb","/positionalAudio1/switch1":"audio/switch","/positionalAudio1/switch2":"audio/switch","/positionalAudio1/volume1":"audio/volume","/audioListener1":"obj/audioListener","/musicBoxes":"obj/geo","/musicBoxes/ANIM":"sop/animationsNetwork","/musicBoxes/ANIM/PLAY":"anim/null","/musicBoxes/ANIM/PLAY1":"anim/null","/musicBoxes/ANIM/RESET":"anim/null","/musicBoxes/ANIM/RESET1":"anim/null","/musicBoxes/ANIM/duration1":"anim/duration","/musicBoxes/ANIM/duration2":"anim/duration","/musicBoxes/ANIM/duration3":"anim/duration","/musicBoxes/ANIM/duration5":"anim/duration","/musicBoxes/ANIM/easing1":"anim/easing","/musicBoxes/ANIM/easing2":"anim/easing","/musicBoxes/ANIM/easing3":"anim/easing","/musicBoxes/ANIM/easing4":"anim/easing","/musicBoxes/ANIM/operation1":"anim/operation","/musicBoxes/ANIM/operation2":"anim/operation","/musicBoxes/ANIM/position1":"anim/position","/musicBoxes/ANIM/position2":"anim/position","/musicBoxes/ANIM/position3":"anim/position","/musicBoxes/ANIM/position4":"anim/position","/musicBoxes/ANIM/propertyName1":"anim/propertyName","/musicBoxes/ANIM/propertyName2":"anim/propertyName","/musicBoxes/ANIM/propertyValue1":"anim/propertyValue","/musicBoxes/ANIM/propertyValue2":"anim/propertyValue","/musicBoxes/ANIM/propertyValue3":"anim/propertyValue","/musicBoxes/ANIM/propertyValue4":"anim/propertyValue","/musicBoxes/ANIM/switch1":"anim/switch","/musicBoxes/ANIM/target1":"anim/target","/musicBoxes/ANIM/target2":"anim/target","/musicBoxes/EVENTS":"sop/eventsNetwork","/musicBoxes/EVENTS/animation2":"event/animation","/musicBoxes/EVENTS/audio1":"event/audio","/musicBoxes/EVENTS/intersectData_ID":"event/intersectData","/musicBoxes/EVENTS/intersectData_NOTE":"event/intersectData","/musicBoxes/EVENTS/mouse1":"event/mouse","/musicBoxes/EVENTS/nodeCook1":"event/nodeCook","/musicBoxes/EVENTS/param4":"event/param","/musicBoxes/EVENTS/raycast1":"event/raycast","/musicBoxes/EVENTS/scene1":"event/scene","/musicBoxes/EVENTS/setParam1":"event/setParam","/musicBoxes/EVENTS/viewer1":"event/viewer","/musicBoxes/MAT":"sop/materialsNetwork","/musicBoxes/MAT/meshStandard1":"mat/meshStandard","/musicBoxes/actor1":"sop/actor","/musicBoxes/actor1/add1":"actor/add","/musicBoxes/actor1/floatToVec3_1":"actor/floatToVec3","/musicBoxes/actor1/getObjectAttribute1":"actor/getObjectAttribute","/musicBoxes/actor1/getObjectAttribute2":"actor/getObjectAttribute","/musicBoxes/actor1/mult1":"actor/mult","/musicBoxes/actor1/onEventObjectHovered1":"actor/onObjectHover","/musicBoxes/actor1/onEventTick1":"actor/onTick","/musicBoxes/actor1/playInstrumentNote1":"actor/playInstrumentNote","/musicBoxes/actor1/setObjectRotation1":"actor/setObjectRotation","/musicBoxes/actor1/triggerFilter1":"actor/triggerFilter","/musicBoxes/actor1/setObjectAttribute2":"actor/setObjectAttribute","/musicBoxes/attribCreate1":"sop/attribCreate","/musicBoxes/attribCreate2":"sop/attribCreate","/musicBoxes/attribCreate3":"sop/attribCreate","/musicBoxes/attribCreate4":"sop/attribCreate","/musicBoxes/attribCreate5":"sop/attribCreate","/musicBoxes/attribPromote1":"sop/attribPromote","/musicBoxes/attribRemap1":"sop/attribRemap","/musicBoxes/audioNotes1":"sop/audioNotes","/musicBoxes/copy1":"sop/copy","/musicBoxes/line1":"sop/line","/musicBoxes/material1":"sop/material","/musicBoxes/objectProperties1":"sop/objectProperties","/musicBoxes/palette2":"sop/palette","/musicBoxes/roundedBox1":"sop/roundedBox","/musicBoxes/transform1":"sop/transform","/musicBoxes/transform2":"sop/transform","/rotatingSpheres":"obj/geo","/rotatingSpheres/MAT":"sop/materialsNetwork","/rotatingSpheres/MAT/meshPhysicalBuilder1":"mat/meshPhysicalBuilder","/rotatingSpheres/instance1":"sop/instance","/rotatingSpheres/scatter1":"sop/scatter","/rotatingSpheres/sphere1":"sop/sphere","/rotatingSpheres/transform1":"sop/transform","/rotatingSpheres/tube1":"sop/tube","/perspectiveCamera_MAIN":"obj/perspectiveCamera","/perspectiveCamera_MAIN/events1":"sop/eventsNetwork","/perspectiveCamera_MAIN/events1/cameraOrbitControls1":"event/cameraOrbitControls","/perspectiveCamera_MAIN/renderersNetwork1":"sop/renderersNetwork","/perspectiveCamera_MAIN/renderersNetwork1/WebGLRenderer1":"rop/WebGLRenderer","/perspectiveCamera_DEBUG":"obj/perspectiveCamera","/perspectiveCamera_DEBUG/events1":"sop/eventsNetwork","/perspectiveCamera_DEBUG/events1/cameraOrbitControls2":"event/cameraOrbitControls","/null2":"obj/null"}
Js version
Editor version
Engine version
Logout
0%
There was a problem displaying your scene:
view scene source