├── geometry
└── plane.json
├── index.html
├── js
├── Main.js
├── Utils.js
└── elements
│ ├── Gem.js
│ ├── Sky.js
│ └── Terrain.js
├── lib
├── three.min.js
└── uil.min.js
├── readme.md
└── shaders
├── Gem.fs
├── Gem.vs
├── Sky.fs
├── Sky.vs
├── Terrain.fs
└── Terrain.vs
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | FindingLove
10 |
11 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/js/Main.js:
--------------------------------------------------------------------------------
1 | class Main {
2 | constructor() {
3 | this.initThree();
4 | this.resize();
5 | this.initUIL();
6 | requestAnimationFrame(this.render.bind(this));
7 | }
8 |
9 | initThree () {
10 | this.scene = new THREE.Scene();
11 | this.renderer = new THREE.WebGLRenderer();
12 | this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
13 | this.controls = new THREE.OrbitControls(this.camera);
14 | this.camera.position.z = 4;
15 | document.body.appendChild(this.renderer.domElement);
16 | window.onresize = () => this.resize();
17 |
18 | let _this = this;
19 |
20 | let view = (function() {
21 | let hash = location.hash.slice(1);
22 | switch (hash) {
23 | case 'Gem': return new Gem(); break;
24 | case 'Sky': return new Sky(); break;
25 | case 'Terrain':
26 | _this.camera.position.z = 50;
27 | _this.camera.position.y = 30;
28 | return new Terrain();
29 | break;
30 | default: throw 'No view found';
31 | }
32 | })();
33 | this.scene.add(view.group);
34 | this.view = view;
35 | }
36 |
37 | initUIL() {
38 | window.uil = new UIL.Gui({css:'top: 0; right: 50px;', size: 300, center: true});
39 | }
40 |
41 | resize() {
42 | this.renderer.setSize(window.innerWidth, window.innerHeight);
43 | this.renderer.setPixelRatio(window.devicePixelRatio);
44 | }
45 |
46 | render() {
47 | this.view.update && this.view.update();
48 | this.controls.update();
49 | this.renderer.render(this.scene, this.camera);
50 | requestAnimationFrame(this.render.bind(this));
51 | }
52 | }
53 |
54 | window.onload = () => new Main();
55 |
--------------------------------------------------------------------------------
/js/Utils.js:
--------------------------------------------------------------------------------
1 | class Utils {
2 | static toRadians(deg) {
3 | return deg * (Math.PI/180);
4 | }
5 |
6 | static headsTails(heads, tails) {
7 | return !Utils.doRandom(0, 1) ? heads : tails;
8 | }
9 |
10 | static doRandom(min, max, precision) {
11 | function rand(min, max) {
12 | return lerp(Math.random(), min, max);
13 | }
14 |
15 | function lerp(ratio, start, end) {
16 | return start + (end - start) * ratio;
17 | }
18 |
19 | if (typeof precision == 'number') {
20 | var p = Math.pow(10, precision);
21 | return Math.round(rand(min, max) * p) / p;
22 | } else {
23 | return Math.round(rand(min - 0.5, max + 0.5));
24 | }
25 | }
26 |
27 | static loadShader(name) {
28 | return new Promise((resolve, reject) => {
29 | Promise.all([fetch(`shaders/${name}.vs`), fetch(`shaders/${name}.fs`)]).then(data => {
30 | let vs, fs;
31 | data.forEach(response => {
32 | if (response.url.indexOf('vs') > -1) vs = response.text();
33 | else fs = response.text();
34 | });
35 |
36 | Promise.all([vs, fs]).then(data => {
37 | vs = data[0];
38 | fs = data[1];
39 |
40 | resolve({vs, fs});
41 | });
42 | })
43 |
44 | });
45 | }
46 |
47 | static loadGeometry(name) {
48 | return new Promise((resolve, reject) => {
49 | fetch(`geometry/${name}.json`).then(response => {
50 | response.text().then(text => {
51 | let loader = new THREE.BufferGeometryLoader();
52 | let geom = loader.parse(JSON.parse(text));
53 | console.log(geom);
54 | resolve(geom);
55 | });
56 | })
57 |
58 | });
59 | }
60 |
61 | static range(oldValue, oldMin, oldMax, newMin, newMax, clamped) {
62 | let oldRange = (oldMax - oldMin);
63 | let newRange = (newMax - newMin);
64 | let newValue = (((oldValue - oldMin) * newRange) / oldRange) + newMin;
65 | if (clamped) return _this.clamp(newValue, Math.min(newMin, newMax), Math.max(newMin, newMax));
66 | return newValue;
67 | }
68 | }
69 |
70 | class ShaderUIL {
71 | constructor(mat) {
72 | this.group = window.uil.add('group', {name: location.hash.slice(1)});
73 | this.group.open();
74 |
75 | for (var key in mat.uniforms) {
76 | let obj = mat.uniforms[key];
77 | switch (obj.type) {
78 | case 'f': this.createNumber(obj, key); break;
79 | case 'c': this.createColor(obj, key); break;
80 | }
81 | }
82 | }
83 |
84 | createNumber(obj, key) {
85 | let params = {
86 | name: key,
87 | type: 'html',
88 | value: obj.value,
89 | callback: val => {
90 | obj.value = val;
91 | }
92 | };
93 |
94 | this.group.add('number', params);
95 | }
96 |
97 | createColor(obj, key) {
98 | let params = {
99 | name: key,
100 | type: 'html',
101 | value: obj.value.getHex(),
102 | callback: val => {
103 | if (Array.isArray(val)) obj.value.setRGB(val[0], val[1], val[2]);
104 | else obj.value.set(val);
105 | }
106 | };
107 |
108 | this.group.add('color', params);
109 | }
110 |
111 | static push(mat) {
112 | new ShaderUIL(mat);
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/js/elements/Gem.js:
--------------------------------------------------------------------------------
1 | class Gem {
2 | constructor() {
3 | this.group = new THREE.Group();
4 |
5 | Utils.loadShader('Gem').then(obj => {
6 | let geom = new THREE.TetrahedronGeometry(1.5, 0);
7 | this.mat = this.getShader(obj.vs, obj.fs);
8 | let mesh = new THREE.Mesh(geom, this.mat);
9 | this.group.add(mesh);
10 |
11 | ShaderUIL.push(this.mat);
12 | });
13 | }
14 |
15 | getShader(vs, fs) {
16 | let uniforms = {
17 | lightColor: {type: 'c', value: new THREE.Color(0xA06CD5)},
18 | strength: { type: 'f', value: 1.1 },
19 | shininess: { type: 'f', value: 1 },
20 | radius: { type: 'f', value: 1 },
21 | time: { type: 'f', value: 1 },
22 | LTPower: { type: 'f', value: 0 },
23 | LTScale: { type: 'f', value: 0.2 },
24 | LTDistortion: { type: 'f', value: 0 },
25 | LTAmbient: { type: 'f', value: 1 },
26 | darkness: {type: 'f', value: 0}
27 | };
28 |
29 | let shader = new THREE.ShaderMaterial({
30 | vertexShader: vs,
31 | fragmentShader: fs,
32 | uniforms
33 | });
34 |
35 | // shader.wireframe = true;
36 |
37 | return shader;
38 | }
39 |
40 | update() {
41 | if (this.mat) {
42 | this.mat.uniforms.time.value = performance.now() * 0.00025;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/js/elements/Sky.js:
--------------------------------------------------------------------------------
1 | class Sky {
2 | constructor() {
3 | this.group = new THREE.Group();
4 |
5 | Utils.loadShader('Sky').then(obj => {
6 | let geom = new THREE.IcosahedronGeometry(100, 4);
7 | this.mat = this.getShader(obj.vs, obj.fs);
8 | let mesh = new THREE.Mesh(geom, this.mat);
9 | this.group.add(mesh);
10 |
11 | ShaderUIL.push(this.mat);
12 | });
13 | }
14 |
15 | getShader(vs, fs) {
16 | let uniforms = {
17 | time: {type: 'f', value: 0},
18 | sat: {type: 'f', value: 0},
19 | color: {type: 'c', value: new THREE.Color(0x49BEAA)}
20 | };
21 |
22 | let shader = new THREE.ShaderMaterial({
23 | vertexShader: vs,
24 | fragmentShader: fs,
25 | uniforms
26 | });
27 |
28 | shader.side = THREE.BackSide;
29 |
30 | return shader;
31 | }
32 |
33 | update() {
34 | if (this.mat) {
35 | this.mat.uniforms.time.value = performance.now() * 0.000025;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/js/elements/Terrain.js:
--------------------------------------------------------------------------------
1 | class Terrain {
2 | constructor() {
3 | this.group = new THREE.Group();
4 |
5 | Promise.all([Utils.loadShader('Terrain'), this.loadGeometry()]).then(data => {
6 | let obj = data[0];
7 | let geom = data[1];
8 | this.mat = this.getShader(obj.vs, obj.fs);
9 | let mesh = new THREE.Mesh(geom, this.mat);
10 | this.group.add(mesh);
11 |
12 | ShaderUIL.push(this.mat);
13 | });
14 | }
15 |
16 | loadGeometry() {
17 | return new Promise((resolve, reject) => {
18 | Utils.loadGeometry('plane').then(geom => {
19 | geom.scale(0.12, 0.12, 0.12);
20 | geom.translate(0, 6, 0);
21 |
22 | geom.computeBoundingBox();
23 |
24 | let posArray = geom.attributes.position.array;
25 | let uvArray = geom.attributes.uv.array;
26 | let count = geom.attributes.uv.count;
27 | for (let i = 0; i < count; i++) {
28 | let x = posArray[i * 3 + 0];
29 | let z = posArray[i * 3 + 2];
30 | let u = Utils.range(x, geom.boundingBox.min.x, geom.boundingBox.max.x, 0, 1);
31 | let v = Utils.range(z, geom.boundingBox.min.z, geom.boundingBox.max.z, 0, 1);
32 | uvArray[i * 2 + 0] = u;
33 | uvArray[i * 2 + 1] = v;
34 | }
35 |
36 | resolve(geom);
37 | });
38 | });
39 | }
40 |
41 | getShader(vs, fs) {
42 | let uniforms = {
43 | time: {type: 'f', value: 0},
44 | transition: {type: 'f', value: 1},
45 | transHeight: {type: 'f', value: 1},
46 | transDirection: {type: 'f', value: 1},
47 | baseColor: {type: 'c', value: new THREE.Color(0xfef0ff)},
48 | multiplyColor: {type: 'c', value: new THREE.Color(0xead4ed)},
49 | lightPos: {type: 'v3', value: new THREE.Vector3(100, 100, 0)},
50 | lightColor: {type: 'c', value: new THREE.Color(0xfff9e6)}
51 | };
52 |
53 | let shader = new THREE.ShaderMaterial({
54 | vertexShader: vs,
55 | fragmentShader: fs,
56 | uniforms
57 | });
58 |
59 | shader.extensions.derivatives = true;
60 |
61 | // shader.wireframe = true;
62 |
63 | return shader;
64 | }
65 |
66 | update() {
67 | if (this.mat) {
68 | this.mat.uniforms.time.value = performance.now() * 0.00025;
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/lib/uil.min.js:
--------------------------------------------------------------------------------
1 | 'use strict';var UMC=UMC||function(){var a=document,b=a.getElementsByTagName("head")[0],c="height width top left bottom right margin-left margin-right margin-top margin-bottom".split(" "),d="pattern defs transform stop animate radialGradient linearGradient animateMotion".split(" "),e="rect circle path polygon text g line foreignObject".split(" "),f=new Image,h=a.createDocumentFragment();UMC=function(){};UMC.frag=function(){return h};UMC.setSvg=function(a,b,c,d){-1===d?a.setAttributeNS(null,b,c):a.childNodes[d||
2 | 0].setAttributeNS(null,b,c)};UMC.setDom=function(a,b,d){var e=-1!==c.indexOf(b)?"px":"";a.style[b]=d+e};UMC.clear=function(a){for(UMC.purge(a);a.firstChild;)a.firstChild.firstChild&&UMC.clear(a.firstChild),a.removeChild(a.firstChild)};UMC.purge=function(a){var b=a.attributes,c,d;if(b)for(c=b.length;c--;)d=b[c].name,"function"===typeof a[d]&&(a[d]=null);if(b=a.childNodes)for(c=b.length;c--;)UMC.purge(a.childNodes[c])};UMC.dom=function(b,c,k,h,f,m){c=c||"div";-1!==d.indexOf(c)||-1!==e.indexOf(c)?(void 0===
3 | f&&(f=a.createElementNS("http://www.w3.org/2000/svg","svg")),UMC.add(f,c,h,m)):f=void 0===f?a.createElementNS("http://www.w3.org/1999/xhtml",c):f.appendChild(a.createElementNS("http://www.w3.org/1999/xhtml",c));b&&("UIL"===b?k="-o-user-select:none; -ms-user-select:none; -khtml-user-select:none; -webkit-user-select:none; -moz-user-select:none;position:absolute; pointer-events:none; box-sizing:border-box; margin:0; padding:0; border:none; overflow:hidden; background:none;"+k:"UIL text"===b?k='-o-user-select:none; -ms-user-select:none; -khtml-user-select:none; -webkit-user-select:none; -moz-user-select:none;position:absolute; pointer-events:none; box-sizing:border-box; margin:0; padding:0; border:none; overflow:hidden; background:none;font-family:"Lucida Console", Monaco, monospace; font-size:11px; color:#CCC; padding:2px 10px; left:0; top:2px; height:16px; width:100px; overflow:hidden; white-space: nowrap;'+
4 | k:"UIL textSelect"===b?k='-o-user-select:none; -ms-user-select:none; -khtml-user-select:none; -webkit-user-select:none; -moz-user-select:none;position:absolute; pointer-events:none; box-sizing:border-box; margin:0; padding:0; border:none; overflow:hidden; background:none;-o-user-select:none; -ms-user-select:none; -khtml-user-select:none; -webkit-user-select:none; -moz-user-select:none;position:absolute; pointer-events:none; box-sizing:border-box; margin:0; padding:0; border:none; overflow:hidden; background:none;font-family:"Lucida Console", Monaco, monospace; font-size:11px; color:#CCC; padding:2px 10px; left:0; top:2px; height:16px; width:100px; overflow:hidden; white-space: nowrap;pointer-events:auto; padding:2px 5px; outline:none; -webkit-appearance:none; -moz-appearance:none; border:1px dashed #4f4f4f; -ms-user-select:element;'+
5 | k:"UIL number"===b?k='-o-user-select:none; -ms-user-select:none; -khtml-user-select:none; -webkit-user-select:none; -moz-user-select:none;position:absolute; pointer-events:none; box-sizing:border-box; margin:0; padding:0; border:none; overflow:hidden; background:none;-o-user-select:none; -ms-user-select:none; -khtml-user-select:none; -webkit-user-select:none; -moz-user-select:none;position:absolute; pointer-events:none; box-sizing:border-box; margin:0; padding:0; border:none; overflow:hidden; background:none;font-family:"Lucida Console", Monaco, monospace; font-size:11px; color:#CCC; padding:2px 10px; left:0; top:2px; height:16px; width:100px; overflow:hidden; white-space: nowrap;letter-spacing:-1px; padding:2px 5px;'+
6 | k:f.setAttribute("class",b));k&&(f.style.cssText=k);return void 0===m?f:f.childNodes[m||0]};UMC.cc=function(c,d,e){e=void 0===e?".":"";"*"===c&&(e="");var f=a.createElement("style");f.type="text/css";b.appendChild(f);(f.sheet||{}).insertRule?f.sheet.insertRule(e+c+"{"+d+"}",0):(f.styleSheet||f.sheet).addRule(e+c,d)};UMC.clone=function(a,b){void 0===b&&(b=!0);return a.cloneNode(b)};UMC.add=function(a,b,c,d){var f=document.createElementNS("http://www.w3.org/2000/svg",b);this.set(f,c);this.get(a,d).appendChild(f);
7 | -1!==e.indexOf(b)&&(f.style.pointerEvents="none");return f};UMC.set=function(a,b){for(var c in b)"txt"===c&&(a.textContent=b[c]),a.setAttributeNS(null,c,b[c])};UMC.get=function(a,b){if(void 0===b)return a;if(!isNaN(b))return a.childNodes[b];if(b instanceof Array){if(2===b.length)return a.childNodes[b[0]].childNodes[b[1]];if(3===b.length)return a.childNodes[b[0]].childNodes[b[1]].childNodes[b[2]]}};UMC.toCanvas=function(a,b,c,d){var e=a.getContext("2d");a=null;"string"===typeof b?(a=UMC.dom(null,"iframe",
8 | "position:abolute; left:0; top:0; width:"+c+"px; height:"+d+"px;"),a.src=b):(a=b.cloneNode(!0),a.style.left=0);b=UMC.dom(null,"foreignObject","position:abolute; left:0; top:0;",{width:c,height:d});b.childNodes[0].appendChild(a);b.setAttribute("version","1.1");b.setAttribute("xmlns","http://www.w3.org/2000/svg");b.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink");b.setAttribute("width",c);b.setAttribute("height",d);b.childNodes[0].setAttribute("width","100%");b.childNodes[0].setAttribute("height",
9 | "100%");b="data:image/svg+xml;base64,"+window.btoa((new XMLSerializer).serializeToString(b));a=null;f.src=b;setTimeout(function(){e.clearRect(0,0,c,d);e.drawImage(f,0,0,c,d,0,0,c,d)},0)};return UMC}();var define,module,exports,performance,UIL=function(){UIL={REVISION:1,frag:UMC.frag,DOM:UMC.dom,clear:UMC.clear,setSvg:UMC.setSvg,isLoop:!1,listens:[],main:null,DEF:!1,WIDTH:240,HEIGHT:20,P:30,BASIC:"-o-user-select:none; -ms-user-select:none; -khtml-user-select:none; -webkit-user-select:none; -moz-user-select:none; position:absolute; pointer-events:none; box-sizing:border-box; margin:0; padding:0; border:none; background:none;",COLOR:"N",BASECOLOR:"#C0C0C0",BUTTON:"#404040",BOOLBG:"#181818",SELECT:"#308AFF",
10 | MOVING:"#03afff",SELECTDOWN:"#024699",BG:"rgba(0,0,0,0.3)",SVGB:"rgba(0,0,0,0.3)",SVGC:"rgba(120,120,120,0.6)",Border:"#4f4f4f",BorderSelect:"#308AFF",setText:function(a,b,c){UIL.TXT=UIL.BASIC+"font-family:"+(c||'"Consolas", "Lucida Console", Monaco, monospace')+"; font-size:"+(a||11)+"px; color:"+(b||"#CCC")+"; padding:2px 10px; left:0; top:2px; height:16px; width:100px; overflow:hidden; white-space: nowrap;";UIL.TXTSELECT=UIL.TXT+"pointer-events:auto; padding:2px 5px; outline:none; -webkit-appearance:none; -moz-appearance:none; border:1px dashed "+
11 | UIL.Border+"; -ms-user-select:element;";UIL.NUM=UIL.TXT+"letter-spacing:-1px; padding:2px 5px;";UIL.ITEM=UIL.TXT+"position:relative; background:rgba(0,0,0,0.2); margin-bottom:1px; pointer-events:auto; cursor:pointer;"},GPATH:"M 7 7 L 7 8 8 8 8 7 7 7 M 5 7 L 5 8 6 8 6 7 5 7 M 3 7 L 3 8 4 8 4 7 3 7 M 7 5 L 7 6 8 6 8 5 7 5 M 6 6 L 6 5 5 5 5 6 6 6 M 7 3 L 7 4 8 4 8 3 7 3 M 6 4 L 6 3 5 3 5 4 6 4 M 3 5 L 3 6 4 6 4 5 3 5 M 3 3 L 3 4 4 4 4 3 3 3 Z"};UIL.setText();return UIL}();
12 | (function(a){"function"===typeof define&&define.amd?define("uil",UIL):"undefined"!==typeof exports&&"undefined"!==typeof module?module.exports=UIL:a.UIL=UIL})(this);UIL.loop=function(){UIL.isLoop&&requestAnimationFrame(UIL.loop);UIL.update()};UIL.update=function(){for(var a=UIL.listens.length;a--;)UIL.listens[a].listening()};UIL.removeListen=function(a){a=UIL.listens.indexOf(a);UIL.listens.splice(a,1);0===UIL.listens.length&&(UIL.isLoop=!1)};UIL.addListen=function(a){-1===UIL.listens.indexOf(a)&&(UIL.listens.push(a),UIL.isLoop||(UIL.isLoop=!0,UIL.loop()))};
13 | UIL.add=function(){var a=arguments,b,c,d=!1;"string"===typeof a[0]?(b=a[0][0].toUpperCase()+a[0].slice(1),c=a[1]||{}):"object"===typeof a[0]&&(d=!0,void 0===a[2]&&[].push.call(a,{}),b=UIL.autoType.apply(this,a),c=a[2],c.name=a[1],c.value=a[0][a[1]]);b=new UIL[b](c);d&&b.setReferency(a[0],a[1]);return b};UIL.autoType=function(){var a=arguments,b="Slide";a[2].type&&(b=a[2].type);return b};
14 | UIL.ColorLuma=function(a,b){a=String(a).replace(/[^0-9a-f]/gi,"");6>a.length&&(a=a[0]+a[0]+a[1]+a[1]+a[2]+a[2]);b=b||0;var c="#",d,e;for(e=0;3>e;e++)d=parseInt(a.substr(2*e,2),16),d=Math.round(Math.min(Math.max(0,d+d*b),255)).toString(16),c+=("00"+d).substr(d.length);return c};UIL.findDeepInver=function(a){return 0.6>=0.3*a[0]+0.59*a[1]+0.11*a[2]};UIL.hexToHtml=function(a){return"#"+("000000"+(void 0===a?0:a).toString(16)).substr(-6)};UIL.htmlToHex=function(a){return a.toUpperCase().replace("#","0x")};
15 | UIL.u255=function(a,b){return parseInt(a.substring(b,b+2),16)/255};UIL.u16=function(a,b){return parseInt(a.substring(b,b+1),16)/15};UIL.unpack=function(a){if(7==a.length)return[UIL.u255(a,1),UIL.u255(a,3),UIL.u255(a,5)];if(4==a.length)return[UIL.u16(a,1),UIL.u16(a,2),UIL.u16(a,3)]};UIL.htmlRgb=function(a){return"rgb("+Math.round(255*a[0])+","+Math.round(255*a[1])+","+Math.round(255*a[2])+")"};UIL.rgbToHex=function(a){return"#"+("000000"+(255*a[0]<<16^255*a[1]<<8^255*a[2]<<0).toString(16)).slice(-6)};
16 | UIL.hueToRgb=function(a,b,c){0>c&&(c+=1);1c?b:c<2/3?a+6*(b-a)*(2/3-c):a};UIL.rgbToHsl=function(a){var b=a[0],c=a[1];a=a[2];var d=Math.min(b,c,a),e=Math.max(b,c,a),f=e-d,h=0,g=0,d=(d+e)/2;0d&&(g=f/(0.5>d?2*d:2-2*d));0=a?a*(b+1):a+b-a*b;a=2*a-b;return[UIL.hueToRgb(a,b,c+0.33333),UIL.hueToRgb(a,b,c),UIL.hueToRgb(a,b,c-0.33333)]};UIL.Gui=function(a){a=a||{};void 0!==a.Tpercent&&(UIL.P=a.Tpercent);void 0===a.css&&(a.css="");this.height=20;this.width=void 0!==a.width?a.width:UIL.WIDTH;this.width=void 0!==a.size?a.size:this.width;this.left=0;this.top=a.top||0;this.h=0;this.prevY=-1;this.isWithClose=!0;this.bh=a.bh||20;void 0!==a.close&&(this.bh=(this.isWithClose=a.close)?this.bh:0);this.sw=a.sw||10;UIL.main=this;this.callback=void 0===a.callback?null:a.callback;this.color=a.color||UIL.COLOR;this.bg=a.bg||"rgba(44,44,44,0.3)";
18 | this.isCenter=a.center||!1;this.onWheel=this.lockwheel=!1;this.isOpen=!0;this.uis=[];this.content=UIL.DOM(null,"div",UIL.BASIC+"display:block; width:"+this.width+"px; height:auto; top:0; right:10px; transition:height 0.1s ease-out;"+a.css);document.body.appendChild(this.content);this.innerContent=UIL.DOM(null,"div",UIL.BASIC+"width:100%; top:0; left:0; height:auto;overflow:hidden;");this.content.appendChild(this.innerContent);this.inner=UIL.DOM(null,"div",UIL.BASIC+"width:100%; top:0; left:0; height:auto;");
19 | this.innerContent.appendChild(this.inner);this.inner.name="inner";this.scrollBG=UIL.DOM(null,"div",UIL.BASIC+"right:0; top:0; width:10px; height:10px; cursor:s-resize; pointer-events:auto; display:none;");this.content.appendChild(this.scrollBG);this.scrollBG.name="scroll";this.scroll=UIL.DOM(null,"div",UIL.BASIC+"background:#666; right:0; top:0; width:5px; height:10px;");this.scrollBG.appendChild(this.scroll);this.bottom=UIL.DOM(null,"div",UIL.TXT+"width:100%; top:auto; bottom:0; left:0; border-bottom-right-radius:10px; border-bottom-left-radius:10px; text-align:center; pointer-events:auto; cursor:pointer; height:"+
20 | this.bh+"px; line-height:"+(this.bh-5)+"px;");this.content.appendChild(this.bottom);this.bottom.textContent="close";this.bottom.name="bottom";this.bottom.style.background=this.bg;this.isScroll=this.isDown=!1;this.callbackClose=function(){};this.content.addEventListener("mousedown",this,!1);this.content.addEventListener("mousemove",this,!1);this.content.addEventListener("mouseout",this,!1);this.content.addEventListener("mouseup",this,!1);this.content.addEventListener("mouseover",this,!1);document.addEventListener("mousewheel",
21 | function(a){this.wheel(a)}.bind(this),!1);window.addEventListener("resize",function(a){this.resize(a)}.bind(this),!1);this.setWidth(this.width)};
22 | UIL.Gui.prototype={constructor:UIL.Gui,hide:function(a){this.content.style.display=a?"none":"block"},setBG:function(a){this.bg=a;for(var b=this.uis.length;b--;)this.uis[b].setBG(a);this.bottom.style.background=a},getHTML:function(){return this.content},onChange:function(a){this.callback=a;return this},handleEvent:function(a){switch(a.type){case "mousedown":this.down(a);break;case "mouseout":this.out(a);break;case "mouseover":this.over(a);break;case "mouseup":this.up(a);break;case "mousemove":this.move(a)}},
23 | down:function(a){a.target.name&&("scroll"===a.target.name&&(this.isDown=!0,this.move(a),document.addEventListener("mouseup",this,!1),document.addEventListener("mousemove",this,!1)),"bottom"===a.target.name&&(this.isOpen=this.isOpen?!1:!0,this.bottom.textContent=this.isOpen?"close":"open",this.testHeight()))},move:function(a){this.isDown&&(this.scroll.style.background="#AAA",this.update(a.clientY-this.top-0.5*this.sh))},out:function(a){a.target.name&&("scroll"===a.target.name&&(this.scroll.style.background=
24 | "#666"),"bottom"===a.target.name&&(this.bottom.style.color="#CCC"))},up:function(a){this.isDown=!1;this.scroll.style.background="#666";document.removeEventListener("mouseup",this,!1);document.removeEventListener("mousemove",this,!1)},over:function(a){a.target.name&&("scroll"===a.target.name&&(this.scroll.style.background="#888"),"bottom"===a.target.name&&(this.bottom.style.color="#FFF"))},wheel:function(a){if(!this.lockwheel&&this.isScroll){var b=a.clientX,c=this.content.getBoundingClientRect().left;
25 | bc+this.width||(b=0,a.wheelDeltaY?b=0.04*-a.wheelDeltaY:a.wheelDelta?b=0.2*-a.wheelDelta:a.detail&&(b=4*a.detail),this.py+=b,this.update(this.py))}},add:function(){var a=arguments;"object"===typeof a[1]?(a[1].isUI=!0,a[1].main=this):"string"===typeof a[1]&&(void 0===a[2]?[].push.call(a,{isUI:!0,main:this}):(a[2].isUI=!0,a[2].main=this));a=UIL.add.apply(this,a);this.uis.push(a);a.py=this.h;if(a.autoWidth)this.prevY=-1,this.calc(a.h+1);else{var b=a.c[0].getBoundingClientRect().top;this.prevY!==
26 | b&&(this.calc(a.h+1),this.prevY=b)}return a},remove:function(a){a=this.uis.indexOf(a);-1!==a&&this.uis[a].clear()},clearOne:function(a){a=this.uis.indexOf(a);-1!==a&&(this.inner.removeChild(this.uis[a].c[0]),this.uis.splice(a,1))},clear:function(){for(var a=this.uis.length;a--;)this.uis[a].clear();this.uis=[];UIL.listens=[];this.calc(-this.h)},update:function(a){a=0>a?0:a;a=a>this.range?this.range:a;this.inner.style.top=-~~(a/this.ratio)+"px";this.scroll.style.top=~~a+"px";this.py=a},showScroll:function(a){this.isScroll=
27 | !0;this.total=this.h;this.maxView=this.maxHeight;this.ratio=this.maxView/this.total;this.sh=this.maxView*this.ratio;20>this.sh&&(this.sh=20);this.range=this.maxView-this.sh;this.scrollBG.style.display="block";this.scrollBG.style.height=this.maxView+"px";this.scroll.style.height=this.sh+"px";this.update(0)},hideScroll:function(){this.isScroll=!1;this.update(0);this.scrollBG.style.display="none"},resize:function(a){this.testHeight()},calc:function(a){this.h+=a;clearTimeout(this.tmp);this.tmp=setTimeout(this.testHeight.bind(this),
28 | 10)},testHeight:function(){this.tmp&&clearTimeout(this.tmp);this.height=this.top+this.bh;this.isOpen?(this.maxHeight=window.innerHeight-this.top-this.bh,this.h>this.maxHeight?(this.height=this.maxHeight+this.bh,this.showScroll()):(this.height=this.h+this.bh,this.hideScroll())):this.hideScroll();this.innerContent.style.height=this.height-this.bh+"px";this.content.style.height=this.height+"px";this.bottom.style.top=this.height-this.bh+"px"},setWidth:function(a){a&&(this.width=a);this.content.style.width=
29 | this.width+"px";this.isCenter&&(this.content.style.marginLeft=-~~(0.5*this.width)+"px");for(var b=a=this.uis.length;b--;)this.uis[b].setSize(this.width);for(b=a;b--;)this.uis[b].rSize();this.resize()}};UIL.Proto=function(a){a=a||{};this.main=a.main||null;this.p=UIL.P;void 0!==a.p&&(this.p=a.p);this.autoWidth=!0;this.isGroup=!1;this.parentGroup=null;this.autoHeight=!1;this.isUI=a.isUI||!1;this.isEdit=this.mono=this.isNumber=!1;if(this.simple=a.simple||!1)this.sa=0;this.width=this.isUI?this.main.width:UIL.WIDTH;void 0!==a.width&&(this.width=a.width);void 0!==a.size&&(this.width=a.size);this.setSize(this.width);void 0!==a.sa&&(this.sa=a.sa);void 0!==a.sb&&(this.sb=a.sb);this.simple&&(this.sb=this.width-
30 | this.sa);this.sc=void 0===a.sc?47:a.sc;this.val=this.parent=null;this.isSend=!1;var b=20;this.isUI&&(b=UIL.HEIGHT);this.h=a.h||a.height||b;this.h=11>this.h?11:this.h;this.bgcolor=UIL.COLOR||a.bgcolor;this.bg=this.isUI?this.main.bg:"rgba(44,44,44,0.3)";void 0!==a.bg&&(this.bg=a.bg);this.titleColor=a.titleColor||UIL.BASECOLOR;this.fontColor=a.fontColor||UIL.BASECOLOR;this.colorPlus=UIL.ColorLuma(this.fontColor,0.3);this.txt=a.name||"Proto";this.rename=a.rename||"";this.target=a.target||null;this.callback=
31 | void 0===a.callback?null:a.callback;this.endCallback=null;null===this.callback&&this.isUI&&null!==this.main.callback&&(this.callback=this.main.callback);this.c=[];this.s=[];this.c[0]=UIL.DOM(null,"div",UIL.BASIC+"position:relative; height:20px; float:left; overflow:hidden;");this.s[0]=this.c[0].style;this.isUI&&(this.s[0].marginBottom="1px");this.simple||(this.c[1]=UIL.DOM(null,"div",UIL.TXT),this.s[1]=this.c[1].style,this.c[1].textContent=""===this.rename?this.txt:this.rename,this.s[1].color=this.titleColor);
32 | if(a.pos){this.s[0].position="absolute";for(var c in a.pos)this.s[0][c]=a.pos[c];this.mono=!0}a.css&&(this.s[0].cssText=a.css)};
33 | UIL.Proto.prototype={constructor:UIL.Proto,init:function(){var a=this.s;a[0].height=this.h+"px";this.isUI&&(this.s[0].background=this.bg);this.autoHeight&&(this.s[0].transition="height 0.1s ease-out");void 0!==this.c[1]&&this.autoWidth&&(a[1]=this.c[1].style,a[1].height=this.h-4+"px",a[1].lineHeight=this.h-8+"px");for(var b=UIL.frag(),c=1,d=this.c.length;c!==d;c++)void 0!==this.c[c]&&(b.appendChild(this.c[c]),a[c]=this.c[c].style);null!==this.target?this.target.appendChild(this.c[0]):this.isUI?this.main.inner.appendChild(this.c[0]):
34 | document.body.appendChild(this.c[0]);this.c[0].appendChild(b);this.rSize();this.addEvent()},rename:function(a){this.c[1].textContent=a},setBG:function(a){this.bg=a;this.s[0].background=a},listen:function(){UIL.addListen(this);UIL.listens.push(this);return this},listening:function(){null!==this.parent&&(this.isSend||this.isEdit||this.setValue(this.parent[this.val]))},setValue:function(a){this.value=this.isNumber?this.numValue(a):a;this.update()},update:function(){},onChange:function(a){this.callback=
35 | a;return this},onFinishChange:function(a){this.callback=null;this.endCallback=a;return this},send:function(a){this.isSend=!0;null!==this.parent&&(this.parent[this.val]=a||this.value);this.callback&&this.callback(a||this.value);this.isSend=!1},sendEnd:function(a){this.endCallback&&this.endCallback(a||this.value);null!==this.parent&&(this.parent[this.val]=a||this.value)},clear:function(){this.clearEvent();UIL.clear(this.c[0]);null!==this.target?this.target.removeChild(this.c[0]):this.isUI?this.main.clearOne(this):
36 | document.body.removeChild(this.c[0]);this.target=this.callback=this.s=this.c=null},setSize:function(a){this.autoWidth&&(this.width=a,this.p=void 0===this.p?UIL.P:this.p,this.simple?this.sb=this.width-this.sa:(a=this.p/100*this.width,this.sa=~~a+10,this.sb=~~this.width-a-20))},rSize:function(){this.autoWidth&&(this.s[0].width=this.width+"px",this.simple||(this.s[1].width=this.sa+"px"))},setTypeNumber:function(a){this.isNumber=!0;this.value=0;void 0!==a.value&&(this.value="string"===typeof a.value?
37 | 1*a.value:a.value);this.min=void 0===a.min?-Infinity:a.min;this.max=void 0===a.max?Infinity:a.max;this.precision=void 0===a.precision?2:a.precision;var b;switch(this.precision){case 0:b=1;break;case 1:b=0.1;break;case 2:b=0.01;break;case 3:b=0.001;break;case 4:b=1E-4}this.step=void 0===a.step?b:a.step;this.range=this.max-this.min;this.value=this.numValue(this.value)},numValue:function(a){return 1*Math.min(this.max,Math.max(this.min,a)).toFixed(this.precision)},addEvent:function(){for(var a=this.c.length,
38 | b,c;a--;)if(c=this.c[a],void 0!==c&&void 0!==c.events)for(b=c.events.length;b--;)c.addEventListener(c.events[b],this,!1)},clearEvent:function(){for(var a=this.c.length,b,c;a--;)if(c=this.c[a],void 0!==c&&void 0!==c.events)for(b=c.events.length;b--;)c.removeEventListener(c.events[b],this,!1)},handleEvent:function(a){},setReferency:function(a,b){this.parent=a;this.val=b},display:function(a){this.s[0].display=a?"block":"none"}};UIL.Group=function(a){UIL.Proto.call(this,a);this.isGroup=this.autoHeight=!0;this.baseH=this.h;var b=Math.floor(0.5*this.h)-6;this.isOpen=a.open||!1;this.c[2]=UIL.DOM(null,"div",UIL.BASIC+"width:100%; left:0; height:auto; overflow:hidden; top:"+this.h+"px");this.c[3]=UIL.DOM(null,"path",UIL.BASIC+"position:absolute; width:10px; height:10px; left:0; top:"+b+"px;",{d:UIL.GPATH,fill:this.fontColor,stroke:"none"});this.c[4]=UIL.DOM(null,"path",UIL.BASIC+"position:absolute; width:10px; height:10px; left:4px; top:"+
39 | b+"px;",{d:"M 3 8 L 8 5 3 2 3 8 Z",fill:this.fontColor,stroke:"none"});this.c[5]=UIL.DOM(null,"div",UIL.BASIC+"background:rgba(255, 255, 255, 0.2); width:100%; left:0; height:1px; bottom:0px");b=this.s;b[0].height=this.h+"px";b[1].height=this.h+"px";b[1].pointerEvents="auto";b[1].cursor="pointer";this.c[1].name="group";this.s[1].marginLeft="10px";this.s[1].lineHeight=this.h-4;this.s[1].color=this.fontColor;this.s[1].fontWeight="bold";this.uis=[];this.c[1].events=["click"];this.init();void 0!==a.bg&&
40 | this.setBG(a.bg);this.isOpen&&this.open()};UIL.Group.prototype=Object.create(UIL.Proto.prototype);UIL.Group.prototype.constructor=UIL.Group;UIL.Group.prototype.setBG=function(a){this.s[0].background=a;for(var b=this.uis.length;b--;)this.uis[b].setBG(a)};UIL.Group.prototype.handleEvent=function(a){a.preventDefault();switch(a.type){case "click":this.click(a)}};UIL.Group.prototype.click=function(a){this.isOpen?this.close():this.open()};
41 | UIL.Group.prototype.add=function(){var a=arguments;"object"===typeof a[1]?(a[1].isUI=this.isUI,a[1].target=this.c[2]):"string"===typeof arguments[1]&&(void 0===a[2]?[].push.call(a,{isUI:!0,target:this.c[2]}):(a[2].isUI=!0,a[2].target=this.c[2]));a=UIL.Gui.prototype.add.apply(this,a);a.autoHeight&&(a.parentGroup=this);return a};UIL.Group.prototype.open=function(){this.isOpen=!0;UIL.setSvg(this.c[4],"d","M 5 8 L 8 3 2 3 5 8 Z");this.rSizeContent();this.isUI&&this.main.calc(this.h-this.baseH)};
42 | UIL.Group.prototype.close=function(){this.isUI&&this.main.calc(-(this.h-this.baseH));this.isOpen=!1;UIL.setSvg(this.c[4],"d","M 3 8 L 8 5 3 2 3 8 Z");this.h=this.baseH;this.s[0].height=this.h+"px"};UIL.Group.prototype.clear=function(){this.clearGroup();this.isUI&&this.main.calc(-(this.h+1));UIL.Proto.prototype.clear.call(this)};UIL.Group.prototype.clearGroup=function(){this.close();for(var a=this.uis.length;a--;)this.uis[a].clear(),this.uis.pop();this.uis=[];this.h=this.baseH};
43 | UIL.Group.prototype.calc=function(a){this.isOpen&&(void 0!==a?(this.h+=a,this.isUI&&this.main.calc(a)):this.h=this.c[2].offsetHeight+this.baseH,this.s[0].height=this.h+"px")};UIL.Group.prototype.rSizeContent=function(){for(var a=this.uis.length;a--;)this.uis[a].setSize(this.width),this.uis[a].rSize();this.calc()};
44 | UIL.Group.prototype.rSize=function(){UIL.Proto.prototype.rSize.call(this);var a=this.s;a[3].left=this.sa+this.sb-17+"px";a[1].width=this.width+"px";a[2].width=this.width+"px";this.isOpen&&this.rSizeContent()};UIL.Title=function(a){UIL.Proto.call(this,a);a=a.prefix||"";this.c[2]=UIL.DOM(null,"div",UIL.TXT+"text-align:right; width:60px; line-height:"+(this.h-8)+"px; color:"+this.fontColor);31===this.h&&(this.s[0].height=this.h+"px",this.s[1].top="8px",this.c[2].style.top="8px");this.c[1].textContent=this.txt.substring(0,1).toUpperCase()+this.txt.substring(1).replace("-"," ");this.c[2].textContent=a;this.init()};UIL.Title.prototype=Object.create(UIL.Proto.prototype);UIL.Title.prototype.constructor=UIL.Title;
45 | UIL.Title.prototype.rSize=function(){UIL.Proto.prototype.rSize.call(this);this.s[1].width=this.width-50+"px";this.s[2].left=this.width-76+"px"};UIL.Title.prototype.text=function(a){this.c[1].textContent=a};UIL.Title.prototype.text2=function(a){this.c[2].textContent=a};UIL.String=function(a){UIL.Proto.call(this,a);this.value=a.value||"";this.allway=a.allway||!1;this.c[2]=UIL.DOM(null,"div",UIL.TXTSELECT);this.c[2].name="input";this.c[2].textContent=this.value;this.c[2].events=["mousedown","keydown","keyup","blur","focus"];this.init()};UIL.String.prototype=Object.create(UIL.Proto.prototype);UIL.String.prototype.constructor=UIL.String;
46 | UIL.String.prototype.handleEvent=function(a){switch(a.type){case "mousedown":this.down(a);break;case "blur":this.blur(a);break;case "focus":this.focus(a);break;case "keydown":this.keydown(a);break;case "keyup":this.keyup(a)}};UIL.String.prototype.down=function(a){a.target.contentEditable=!0;a.target.focus();a.target.style.cursor="auto"};UIL.String.prototype.blur=function(a){a.target.style.borderColor=UIL.Border;a.target.contentEditable=!1};
47 | UIL.String.prototype.focus=function(a){a.target.style.borderColor=UIL.BorderSelect};UIL.String.prototype.keydown=function(a){a.stopPropagation();13===a.keyCode&&(a.preventDefault(),this.value=a.target.textContent,a.target.blur(),this.send())};UIL.String.prototype.keyup=function(a){a.stopPropagation();this.value=a.target.textContent;this.allway&&this.send()};
48 | UIL.String.prototype.rSize=function(){UIL.Proto.prototype.rSize.call(this);this.s[2].color=this.fontColor;this.s[2].left=this.sa+"px";this.s[2].width=this.sb+"px";this.s[2].height=this.h-4+"px";this.s[2].lineHeight=this.h-8+"px"};UIL.Number=function(a){UIL.Proto.call(this,a);this.type="number";this.setTypeNumber(a);this.allway=a.allway||!1;this.isDrag=void 0===a.drag?!0:a.drag;this.value=[0];this.toRad=1;this.isNumber=!0;this.isSelect=this.isVector=this.isAngle=!1;void 0!==a.value&&(isNaN(a.value)?a.value instanceof Array?(this.value=a.value,this.isNumber=!1):a.value instanceof Object&&(this.value=[],a.value.x&&(this.value[0]=a.value.x),a.value.y&&(this.value[1]=a.value.y),a.value.z&&(this.value[2]=a.value.z),a.value.w&&(this.value[3]=
49 | a.value.w),this.isVector=!0):this.value=[a.value]);this.length=this.value.length;a.isAngle&&(this.isAngle=!0,this.toRad=Math.PI/180);this.w=(UIL.BW+5)/this.length-5;this.current=void 0;for(var b=this.length;b--;)this.isAngle&&(this.value[b]=(180*this.value[b]/Math.PI).toFixed(this.precision)),this.c[2+b]=UIL.DOM(null,"div",UIL.TXTSELECT+"letter-spacing:-1px; cursor:pointer; height:"+(this.h-4)+"px; line-height:"+(this.h-8)+"px;"),this.c[2+b].name=b,this.isDrag&&(this.c[2+b].style.cursor="move"),a.center&&
50 | (this.c[2+b].style.textAlign="center"),this.c[2+b].textContent=this.value[b],this.c[2+b].style.color=this.fontColor,this.c[2+b].events=["keydown","keyup","mousedown","blur","focus"];this.init()};UIL.Number.prototype=Object.create(UIL.Proto.prototype);UIL.Number.prototype.constructor=UIL.Number;
51 | UIL.Number.prototype.handleEvent=function(a){switch(a.type){case "mousedown":this.down(a);break;case "keydown":this.keydown(a);break;case "keyup":this.keyup(a);break;case "blur":this.blur(a);break;case "focus":this.focus(a);break;case "mouseup":this.up(a);break;case "mousemove":this.move(a)}};UIL.Number.prototype.setValue=function(a,b){b=b||0;this.value[b]=this.numValue(a);this.c[2+b].textContent=this.value[b]};
52 | UIL.Number.prototype.keydown=function(a){a.stopPropagation();13===a.keyCode&&(a.preventDefault(),this.testValue(parseFloat(a.target.name)),this.validate(),a.target.blur())};UIL.Number.prototype.keyup=function(a){a.stopPropagation();this.allway&&(this.testValue(parseFloat(a.target.name)),this.validate())};UIL.Number.prototype.blur=function(a){this.isSelect=!1;a.target.style.borderColor=UIL.Border;a.target.contentEditable=!1;a.target.style.cursor=this.isDrag?"move":"pointer"};
53 | UIL.Number.prototype.focus=function(a){this.isSelect=!0;this.current=void 0;a.target.style.borderColor=UIL.BorderSelect;this.isDrag&&(a.target.style.cursor="auto")};
54 | UIL.Number.prototype.down=function(a){this.isSelect||(a.preventDefault(),this.current=parseFloat(a.target.name),this.prev={x:a.clientX,y:a.clientY,d:0,id:this.current+2},this.prev.v=this.isNumber?parseFloat(this.value):parseFloat(this.value[this.current]),document.addEventListener("mouseup",this,!1),this.isDrag&&document.addEventListener("mousemove",this,!1))};
55 | UIL.Number.prototype.up=function(a){a.preventDefault();document.removeEventListener("mouseup",this,!1);this.isDrag&&document.removeEventListener("mousemove",this,!1);void 0!==this.current&&this.current===parseFloat(a.target.name)&&(a.target.contentEditable=!0,a.target.focus())};
56 | UIL.Number.prototype.move=function(a){a.preventDefault();void 0!==this.current&&(this.prev.d+=a.clientX-this.prev.x-(a.clientY-this.prev.y),this.value[this.current]=this.numValue(this.prev.v+this.prev.d*this.step),this.c[2+this.current].textContent=this.value[this.current],this.validate(),this.prev.x=a.clientX,this.prev.y=a.clientY)};
57 | UIL.Number.prototype.testValue=function(a){if(isNaN(this.c[2+a].textContent))this.c[2+a].textContent=this.value[a];else{var b=this.numValue(this.c[2+a].textContent);this.c[2+a].textContent=b;this.value[a]=b}};UIL.Number.prototype.validate=function(){for(var a=[],b=this.length;b--;)a[b]=this.value[b]*this.toRad;this.isNumber?this.send(a[0]):this.send(a)};
58 | UIL.Number.prototype.rSize=function(){UIL.Proto.prototype.rSize.call(this);this.w=~~((this.sb+5)/this.length)-5;for(var a=this.s,b=this.length;b--;)a[2+b].left=~~(this.sa+this.w*b+5*b)+"px",a[2+b].width=this.w+"px"};UIL.Color=function(a){UIL.Proto.call(this,a);this.autoHeight=!0;this.ctype=a.ctype||"array";this.ww=this.sb;this.oldWidth=0;this.side=a.side||"down";this.holdTop=0;this.wheelWidth=0.1*this.ww;this.decal=this.h+2;this.radius=0.5*(this.ww-this.wheelWidth)-1;this.square=Math.floor(0.7*(this.radius-0.5*this.wheelWidth))-1;this.mid=Math.floor(0.5*this.ww);this.markerSize=0.3*this.wheelWidth;this.baseH=this.h;this.c[2]=UIL.DOM(null,"div",UIL.TXT+"height:"+(this.h-4)+"px;border-radius:3px; pointer-events:auto; cursor:pointer; border:1px solid "+
59 | UIL.Border+"; line-height:"+(this.h-8)+"px;");this.s[2]=this.c[2].style;"up"===this.side&&(this.decal=5,this.s[2].top="auto",this.s[2].bottom="2px");this.c[3]=UIL.DOM(null,"div",UIL.BASIC+"display:none");this.c[4]=UIL.DOM(null,"canvas",UIL.BASIC+"display:none;");this.c[5]=UIL.DOM(null,"canvas",UIL.BASIC+"pointer-events:auto; cursor:pointer; display:none;");this.s[3]=this.c[3].style;this.s[5]=this.c[5].style;"up"===this.side&&(this.s[5].pointerEvents="none");this.c[4].width=this.c[4].height=this.ww;
60 | this.c[5].width=this.c[5].height=this.ww;this.ctxMask=this.c[4].getContext("2d");this.ctxOverlay=this.c[5].getContext("2d");this.ctxMask.translate(this.mid,this.mid);this.ctxOverlay.translate(this.mid,this.mid);this.hsl=null;this.value="#ffffff";void 0!==a.value&&(a.value instanceof Array?this.value=UIL.rgbToHex(a.value):isNaN(a.value)?this.value=a.value:this.value=UIL.hexToHtml(a.value));this.bcolor=null;this.isShow=this.isDown=!1;this.c[2].events=["click"];this.c[5].events=["mousedown","mousemove",
61 | "mouseup","mouseout"];this.setColor(this.value);this.init()};UIL.Color.prototype=Object.create(UIL.Proto.prototype);UIL.Color.prototype.constructor=UIL.Color;UIL.Color.prototype.handleEvent=function(a){a.preventDefault();a.stopPropagation();switch(a.type){case "click":this.click(a);break;case "mousedown":this.down(a);break;case "mousemove":this.move(a);break;case "mouseup":this.up(a);break;case "mouseout":this.out(a)}};UIL.Color.prototype.click=function(a){this.isShow?this.hide():this.show()};
62 | UIL.Color.prototype.up=function(a){this.isDown=!1};UIL.Color.prototype.out=function(a){this.hide()};UIL.Color.prototype.down=function(a){if(this.isShow)return this.isDown=!0,this.move(a),!1};
63 | UIL.Color.prototype.move=function(a){if(this.isDown){this.offset=this.c[5].getBoundingClientRect();var b=a.pageX-this.offset.left-this.mid;a=a.pageY-this.offset.top-this.mid;(this.circleDrag=Math.max(Math.abs(b),Math.abs(a))>this.square+2)?(b=Math.atan2(b,-a)/6.28,this.setHSL([(b+1)%1,this.hsl[1],this.hsl[2]])):(b=Math.max(0,Math.min(1,-(b/this.square*0.5)+0.5)),a=Math.max(0,Math.min(1,-(a/this.square*0.5)+0.5)),this.setHSL([this.hsl[0],b,a]))}};
64 | UIL.Color.prototype.redraw=function(){this.oldWidth=this.ww;this.drawCircle();this.drawMask();this.drawMarkers()};
65 | UIL.Color.prototype.show=function(){this.oldWidth!==this.ww&&this.redraw();this.isShow=!0;this.h=this.ww+this.baseH+10;this.s[0].height=this.h+"px";"up"==this.side&&(this.holdTop=1*this.s[0].top.substring(0,this.s[0].top.length-2)||"auto",isNaN(this.holdTop)||(this.s[0].top=this.holdTop-(this.h-20)+"px"),setTimeout(function(){this.s[5].pointerEvents="auto"}.bind(this),100));this.s[3].display="block";this.s[4].display="block";this.s[5].display="block";null!==this.parentGroup?this.parentGroup.calc(this.h-
66 | this.baseH):this.isUI&&this.main.calc(this.h-this.baseH)};UIL.Color.prototype.hide=function(){null!==this.parentGroup?this.parentGroup.calc(-(this.h-this.baseH)):this.isUI&&this.main.calc(-(this.h-this.baseH));this.isShow=!1;this.h=this.baseH;"up"===this.side&&(isNaN(this.holdTop)||(this.s[0].top=this.holdTop+"px"),this.s[5].pointerEvents="none");this.s[0].height=this.h+"px";this.s[3].display="none";this.s[4].display="none";this.s[5].display="none"};
67 | UIL.Color.prototype.update=function(a){this.s[3].background=UIL.rgbToHex(UIL.hslToRgb([this.hsl[0],1,0.5]));this.drawMarkers();this.value=this.bcolor;this.s[2].background=this.bcolor;this.c[2].textContent=UIL.htmlToHex(this.bcolor);this.invert=UIL.findDeepInver(this.rgb);this.s[2].color=this.invert?"#fff":"#000";a&&("array"===this.ctype&&this.send(this.rgb),"rgb"===this.ctype&&this.send(UIL.htmlRgb(this.rgb)),"hex"===this.ctype&&this.send(UIL.htmlToHex(this.value)),"html"===this.ctype&&this.send())};
68 | UIL.Color.prototype.setColor=function(a){var b=UIL.unpack(a);this.bcolor!=a&&b&&(this.bcolor=a,this.rgb=b,this.hsl=UIL.rgbToHsl(this.rgb),this.update());return this};UIL.Color.prototype.setHSL=function(a){this.hsl=a;this.rgb=UIL.hslToRgb(a);this.bcolor=UIL.rgbToHex(this.rgb);this.update(!0);return this};UIL.Color.prototype.calculateMask=function(a,b,c){for(var d=1/a,e=1/b,f=0;f<=b;++f)for(var h=1-f*e,g=0;g<=a;++g){var l=1-g*d,l=1-2*Math.min(h*l,(1-h)*l);c(g,f,0=k;++k)l=k/24,a=l*Math.PI*2,b=[Math.sin(e),-Math.cos(e),Math.sin(a),-Math.cos(a)],h=0.5*(e+a),g=1/Math.cos(0.5*(a-e)),e=Math.sin(h)*g,h=-Math.cos(h)*g,l=UIL.rgbToHex(UIL.hslToRgb([l,1,0.5])),0=this.step||a<=this.step)a=~~(a/this.step),this.value=this.numValue(this.old+a*this.step),this.update(!0),this.old=this.value};UIL.Slide.prototype.update=function(a){var b=(this.value-this.min)/this.range*this.w;3!==this.stype&&(this.s[5].width=~~b+"px");this.s[6]&&(this.s[6].left=~~(this.sa+b+3)+"px");this.c[2].textContent=this.value;a&&this.send()};
82 | UIL.Slide.prototype.rSize=function(){UIL.Proto.prototype.rSize.call(this);var a=this.sb-this.sc;this.w=a-6;var b=this.sc;if(this.isUI||!this.simple)b=this.sc+10;var c=~~(0.5*this.h)-8,d=this.s;d[2].width=this.sc-2+"px";d[2].left=this.width-b+2+"px";d[2].top=c+"px";d[3].left=this.sa+"px";d[3].width=a+"px";d[4].left=this.sa+"px";d[4].width=a+"px";d[5].left=this.sa+3+"px";this.update()};
83 | UIL.Slide.prototype.validate=function(a){isNaN(this.c[2].textContent)?this.c[2].textContent=this.value:(this.value=this.numValue(this.c[2].textContent),this.update(!0))};UIL.Slide.prototype.textdown=function(a){a.target.contentEditable=!0;a.target.focus();this.isEdit=!0};UIL.Slide.prototype.keydown=function(a){a.stopPropagation();13===a.keyCode&&(a.preventDefault(),this.validate(),a.target.blur())};UIL.Slide.prototype.keyup=function(a){a.stopPropagation();this.allway&&this.validate()};
84 | UIL.Slide.prototype.blur=function(a){a.target.style.border="none";this.isEdit=a.target.contentEditable=!1};UIL.Slide.prototype.focus=function(a){a.target.style.border="1px dashed "+UIL.BorderSelect};UIL.List=function(a){UIL.Proto.call(this,a);this.autoHeight=!0;var b=a.align||"center";this.buttonColor=UIL.BUTTON;var c=Math.floor(0.5*this.h)-5;this.c[2]=UIL.DOM(null,"div",UIL.BASIC+"top:0; height:90px; cursor:s-resize; pointer-events:auto; display:none; overflow:hidden; border:1px solid "+UIL.Border+";");this.c[3]=UIL.DOM(null,"div",UIL.TXT+UIL.BASIC+"text-align:"+b+"; line-height:"+(this.h-4)+"px; border:1px solid "+UIL.Border+"; top:1px; pointer-events:auto; cursor:pointer; background:"+this.buttonColor+
85 | "; height:"+(this.h-2)+"px;");this.c[4]=UIL.DOM(null,"path",UIL.BASIC+"position:absolute; width:10px; height:10px; top:"+c+"px;",{d:"M 3 8 L 8 5 3 2 3 8 Z",fill:this.fontColor,stroke:"none"});this.scroller=UIL.DOM(null,"div",UIL.BASIC+"right:5px; width:10px; pointer-events:none; background:#666; display:none;");this.c[2].name="list";this.c[3].name="title";this.c[3].style.color=this.fontColor;this.c[2].events="mousedown mousemove mouseup mousewheel mouseout mouseover".split(" ");this.c[3].events=
86 | ["mousedown","mouseover","mouseout"];this.list=a.list||[];this.baseH=this.h;this.isShow=!1;this.itemHeight=a.itemHeight||this.h-3;this.full=a.full||!1;this.py=0;this.w=this.sb;this.isDown=this.scroll=!1;this.side=a.side||"down";this.holdTop=0;"up"===this.side?(this.c[2].style.top="auto",this.c[3].style.top="auto",this.c[4].style.top="auto",this.c[2].style.bottom=this.h-2+"px",this.c[3].style.bottom="1px",this.c[4].style.bottom=c+"px"):this.c[2].style.top=this.h-2+"px";this.listIn=UIL.DOM(null,"div",
87 | UIL.BASIC+"left:0; top:0; width:100%; background:rgba(0,0,0,0.2);");this.listIn.name="list";this.c[2].appendChild(this.listIn);this.c[2].appendChild(this.scroller);this.setList(this.list,a.value);this.init()};UIL.List.prototype=Object.create(UIL.Proto.prototype);UIL.List.prototype.constructor=UIL.List;UIL.List.prototype.clearList=function(){for(;this.listIn.children.length;)this.listIn.removeChild(this.listIn.lastChild)};
88 | UIL.List.prototype.setList=function(a,b){this.clearList();this.list=a;this.length=this.list.length;this.maxItem=this.full?this.length:5;this.maxItem=this.lengththis.maxHeight&&
89 | (this.w=this.sb-20,this.scroll=!0);for(var c,d,e=0;ea?0:a,a=a>this.range?this.range:a,this.listIn.style.top=-Math.floor(a/this.ratio)+"px",this.scroller.style.top=Math.floor(a)+"px",this.py=a)};
95 | UIL.List.prototype.listShow=function(){document.addEventListener("click",this,!1);this.update(0);this.isShow=!0;this.h=this.maxHeight+this.baseH+10;this.scroll?this.scroller.style.display="block":(this.h=this.baseH+10+this.max,this.scroller.style.display="none");this.s[0].height=this.h+"px";this.s[2].display="block";"up"===this.side?UIL.setSvg(this.c[4],"d","M 5 2 L 2 7 8 7 5 2 Z"):UIL.setSvg(this.c[4],"d","M 5 8 L 8 3 2 3 5 8 Z");this.rSizeContent();null!==this.parentGroup?this.parentGroup.calc(this.h-
96 | this.baseH):this.isUI&&this.main.calc(this.h-this.baseH)};UIL.List.prototype.listHide=function(){document.removeEventListener("click",this,!1);null!==this.parentGroup?this.parentGroup.calc(-(this.h-this.baseH)):this.isUI&&this.main.calc(-(this.h-this.baseH));this.isShow=!1;this.h=this.baseH;this.s[0].height=this.h+"px";this.s[2].display="none";UIL.setSvg(this.c[4],"d","M 3 8 L 8 5 3 2 3 8 Z")};UIL.List.prototype.text=function(a){this.c[3].textContent=a};
97 | UIL.List.prototype.rSizeContent=function(){for(var a=this.length;a--;)this.listIn.children[a].style.width=this.w+"px"};UIL.List.prototype.rSize=function(){UIL.Proto.prototype.rSize.call(this);var a=this.s,b=this.sb,c=this.sa;a[2].width=b+"px";a[2].left=c+"px";a[3].width=b+"px";a[3].left=c+"px";a[4].left=c+b-17+"px";this.w=b;this.max>this.maxHeight&&(this.w=b-20);this.isShow&&this.rSizeContent()};UIL.Bool=function(a){UIL.Proto.call(this,a);this.value=a.value||!1;this.buttonColor=UIL.BUTTON;this.inh=a.inh||this.h;a=~~(0.5*this.h)-0.5*(this.inh-2);this.c[2]=UIL.DOM(null,"div",UIL.BASIC+"background:"+UIL.BOOLBG+"; height:"+(this.inh-2)+"px; width:36px; top:"+a+"px; border-radius:20px; pointer-events:auto; cursor:pointer; transition:0.1s ease-out;");this.c[3]=UIL.DOM(null,"div",UIL.BASIC+"opasity:0, background:"+UIL.BOOLBG+"; height:"+(this.inh-6)+"px; width:"+(this.inh-6)+"px; top:"+(a+2)+"px; border-radius:20px; ");
98 | this.c[4]=UIL.DOM(null,"div",UIL.BASIC+"border:1px solid "+UIL.Border+"; height:"+(this.inh-4)+"px; width:16px; top:"+(a+1)+"px; border-radius:20px; background:"+this.buttonColor+"; transition:margin 0.1s ease-out;");this.value&&(this.c[4].style.marginLeft="18px",this.c[2].style.background=this.fontColor,this.c[2].style.borderColor=this.fontColor);this.c[2].events=["click"];this.init()};UIL.Bool.prototype=Object.create(UIL.Proto.prototype);UIL.Bool.prototype.constructor=UIL.Bool;
99 | UIL.Bool.prototype.handleEvent=function(a){a.preventDefault();switch(a.type){case "click":this.click(a)}};UIL.Bool.prototype.click=function(a){this.value=this.value?!1:!0;this.update();this.send()};UIL.Bool.prototype.rSize=function(){UIL.Proto.prototype.rSize.call(this);var a=this.s;a[2].left=this.sa+"px";a[3].left=this.sa+1+"px";a[4].left=this.sa+1+"px"};
100 | UIL.Bool.prototype.update=function(){var a=this.s;this.value?(a[4].marginLeft="18px",a[2].background=this.fontColor,a[2].borderColor=this.fontColor,a[4].borderColor=this.fontColor):(a[4].marginLeft="0px",a[2].background=UIL.BOOLBG,a[2].borderColor=UIL.BOOLBG,a[4].borderColor=UIL.Border)};UIL.Button=function(a){UIL.Proto.call(this,a);this.value=a.value||[this.txt];this.buttonColor=a.bColor||UIL.BUTTON;this.isLoadButton=a.loader||!1;if(this.isDragButton=a.drag||!1)this.isLoadButton=!0;this.r=a.r||3;this.lng=this.value.length;for(a=0;aMath.PI?this.oldr:this.r,6a&&(this.r=this.twoPi)),a=1/this.twoPi*this.range*this.r+this.min-this.old,a>=this.step||a<=this.step)&&(a=~~(a/this.step),this.value=this.numValue(this.old+a*this.step),this.update(!0),this.old=
115 | this.value,this.oldr=this.r)};UIL.Circular.prototype.makePath=function(){var a=this.radius,b=this.percent*this.twoPi-0.001,c=a+a*Math.sin(b),d=a-a*Math.cos(b);return"M "+a+","+a+" L "+a+",0 A "+a+","+a+" 0 "+(b>Math.PI?1:0)+" 1 "+c+","+d+" Z"};UIL.Circular.prototype.update=function(a){this.c[2].textContent=this.value;this.percent=(this.value-this.min)/this.range;UIL.setSvg(this.c[4],"d",this.makePath());a&&this.send()};UIL.Knob=function(a){UIL.Proto.call(this,a);this.autoWidth=!1;this.buttonColor=UIL.BUTTON;this.setTypeNumber(a);this.mPI=0.8*Math.PI;this.toDeg=180/Math.PI;this.cirRange=2*this.mPI;this.radius=a.radius||15;this.width=2*this.radius+20;void 0!==a.width&&(this.width=a.width,this.radius=0.5*~~(this.width-20));void 0!==a.size&&(this.width=a.size,this.radius=0.5*~~(this.width-20));this.w=this.height=2*this.radius;this.h=a.height||this.height+40;this.top=0;this.c[0].style.width=this.width+"px";void 0!==
116 | this.c[1]&&(this.c[1].style.width=this.width+"px",this.c[1].style.textAlign="center",this.top=20);this.percent=0;this.c[2]=UIL.DOM(null,"div",UIL.NUM+"text-align:center; top:"+(this.height+24)+"px; width:"+this.width+"px; color:"+this.fontColor);this.c[3]=UIL.DOM(null,"circle",UIL.BASIC+"left:10px; top:"+this.top+"px; width:"+this.w+"px; height:"+this.height+"px; pointer-events:auto; cursor:pointer;",{cx:this.radius,cy:this.radius,r:this.radius-4,fill:"rgba(0,0,0,0.3)"});this.c[4]=UIL.DOM(null,"circle",
117 | UIL.BASIC+"left:10px; top:"+this.top+"px; width:"+this.w+"px; height:"+this.height+"px;",{cx:this.radius,cy:0.5*this.radius,r:3,fill:this.fontColor});this.c[5]=UIL.DOM(null,"path",UIL.BASIC+"left:10px; top:"+this.top+"px; width:"+this.w+"px; height:"+this.height+"px;",{d:this.makeGrad(),"stroke-width":1,stroke:UIL.SVGC});UIL.DOM(null,"circle",null,{cx:this.radius,cy:this.radius,r:0.7*this.radius,fill:this.buttonColor,"stroke-width":1,stroke:UIL.SVGC},this.c[3]);this.c[3].events=["mouseover","mousedown",
118 | "mouseout"];this.r=0;this.init();this.update()};UIL.Knob.prototype=Object.create(UIL.Circular.prototype);UIL.Knob.prototype.constructor=UIL.Knob;
119 | UIL.Knob.prototype.move=function(a){this.isDown&&(this.r=-Math.atan2(this.radius-(a.clientX-this.rect.left),this.radius-(a.clientY-this.rect.top)),null!==this.oldr&&(this.r=Math.abs(this.r-this.oldr)>Math.PI?this.oldr:this.r),this.r=this.r>this.mPI?this.mPI:this.r,this.r=this.r<-this.mPI?-this.mPI:this.r,a=1/this.cirRange*this.range*(this.r+this.mPI)+this.min-this.old,a>=this.step||a<=this.step)&&(a=~~(a/this.step),this.value=this.numValue(this.old+a*this.step),this.update(!0),this.old=this.value,
120 | this.oldr=this.r)};UIL.Knob.prototype.makeGrad=function(){var a="",b,c,d,e,f,h,g=this.radius,l=Math.PI+this.mPI;b=Math.PI-this.mPI;5this.maxDistance&&(a=Math.atan2(b,a),b=Math.sin(a)*this.maxDistance,a=Math.cos(a)*this.maxDistance);this.x=b/this.maxDistance;this.y=a/this.maxDistance;this.update()}};
132 | UIL.Joystick.prototype.update=function(a){void 0===a&&(a=!0);null!==this.interval&&(this.isDown||(this.x+=(0-this.x)/3,this.y+=(0-this.y)/3),this.x.toFixed(2)===this.oldx.toFixed(2)&&this.y.toFixed(2)===this.oldy.toFixed(2)&&(this.y=this.x=0));var b=this.radius-this.x*this.maxDistance,c=this.radius-this.y*this.maxDistance,d=b+5*(1-this.x)+5,e=c+5*(1-this.y)+10;this.value[0]=1*-(this.x*this.multiplicator).toFixed(this.precision);this.value[1]=1*(this.y*this.multiplicator).toFixed(this.precision);this.c[5].textContent=
133 | "x"+this.value[0]+" y"+this.value[1];UIL.setSvg(this.c[3],"cx",d);UIL.setSvg(this.c[3],"cy",e);UIL.setSvg(this.c[4],"cx",b);UIL.setSvg(this.c[4],"cy",c);this.oldx=this.x;this.oldy=this.y;a&&this.send();null!==this.interval&&0===this.x&&0===this.y&&(clearInterval(this.interval),this.interval=null)};UIL.Fps=function(a){UIL.Proto.call(this,a);this.round=Math.round;this.autoHeight=!0;this.baseH=this.h;this.hplus=50;this.res=a.res||40;this.l=1;this.pa1=[];this.pa2=[];this.pa3=[];for(var b=this.res+1;b--;)this.pa1.push(50),this.pa2.push(50),this.pa3.push(50);b=Math.floor(0.5*this.h)-6;this.c[1].textContent="FPS";this.c[0].style.cursor="pointer";this.c[0].style.pointerEvents="auto";this.c[2]=UIL.DOM(null,"path",UIL.BASIC+("display:none; left:10px; top:"+this.h+"px; height:"+(this.hplus-8)+"px; background: rgba(0, 0, 0, 0.2);border:1px solid rgba(255, 255, 255, 0.2); "),
134 | {fill:"rgba(200,200,200,0.3)","stroke-width":1,stroke:this.fontColor,"vector-effect":"non-scaling-stroke"});this.c[2].setAttribute("viewBox","0 0 "+this.res+" 42");this.c[2].setAttribute("height","100%");this.c[2].setAttribute("width","100%");this.c[2].setAttribute("preserveAspectRatio","none");UIL.DOM(null,"path",null,{fill:"rgba(255,255,0,0.3)","stroke-width":1,stroke:"#FF0","vector-effect":"non-scaling-stroke"},this.c[2]);UIL.DOM(null,"path",null,{fill:"rgba(0,255,255,0.3)","stroke-width":1,stroke:"#0FF",
135 | "vector-effect":"non-scaling-stroke"},this.c[2]);this.c[3]=UIL.DOM(null,"div",UIL.BASIC+"width:100%; bottom:0px; height:1px; background: rgba(255, 255, 255, 0.2);");this.c[4]=UIL.DOM(null,"path",UIL.BASIC+"position:absolute; width:10px; height:10px; left:4px; top:"+b+"px;",{d:"M 3 8 L 8 5 3 2 3 8 Z",fill:this.fontColor,stroke:"none"});this.isShow=a.show||!1;this.c[1].style.marginLeft="10px";this.now=self.performance&&self.performance.now?self.performance.now.bind(performance):Date.now;this.prevTime=
136 | this.startTime=this.now();this.frames=0;this.isMem=!1;this.mm=this.mem=this.fps=this.ms=0;self.performance&&self.performance.memory&&(this.isMem=!0);this.c[0].events=["click","mousedown","mouseover","mouseout"];this.init()};UIL.Fps.prototype=Object.create(UIL.Proto.prototype);UIL.Fps.prototype.constructor=UIL.Fps;UIL.Fps.prototype.handleEvent=function(a){a.preventDefault();switch(a.type){case "click":this.click(a);break;case "mouseover":this.mode(1);break;case "mousedown":this.mode(2);break;case "mouseout":this.mode(0)}};
137 | UIL.Fps.prototype.click=function(a){this.isShow?this.hide():this.show()};UIL.Fps.prototype.mode=function(a){var b=this.s;switch(a){case 0:b[1].color=this.fontColor;break;case 1:b[1].color="#FFF";break;case 2:b[1].color=this.fontColor}};UIL.Fps.prototype.makePath=function(a){var b;b="M -1 50";for(var c=0;cthis.prevTime+1E3&&(this.fps=this.round(1E3*this.frames/(a-this.prevTime)),this.prevTime=a,this.frames=0,this.isMem)){var b=performance.memory.usedJSHeapSize,c=performance.memory.jsHeapSizeLimit;this.mem=this.round(9.54E-7*b);this.mm=b/c}this.drawGraph();this.c[1].innerHTML="FPS "+this.fps+' . MS '+(this.ms|0)+' . MB '+this.mem+"";return a};
143 | UIL.Fps.prototype.listening=function(){this.startTime=this.end()};
144 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Finding Love Shaders
2 | This repository demonstrates shaders from 3 prominent elements of the [Finding Love](https://findinglove.activetheory.net) experience.
3 |
4 | The demo code uses latest ES6 features without transpilation, so Chrome is recommended.
5 |
6 | To view, [create a local environment if necessary](https://threejs.org/docs/#Manual/Getting_Started/How_to_run_things_locally), and point your browser to:
7 |
8 | `http://localhost/#Gem`
9 | 
10 |
11 | `http://localhost/#Sky`
12 | 
13 |
14 | `http://localhost/#Terrain`
15 | 
16 |
17 | You'll be able to adjust shader uniforms directly in browser and the shaders themselves are in the `shaders/` folder.
18 |
--------------------------------------------------------------------------------
/shaders/Gem.fs:
--------------------------------------------------------------------------------
1 | uniform vec3 lightColor;
2 | uniform float strength;
3 | uniform float LTPower;
4 | uniform float LTScale;
5 | uniform float LTDistortion;
6 | uniform float LTAmbient;
7 | uniform float shininess;
8 | uniform float radius;
9 | uniform float time;
10 | uniform float darkness;
11 | uniform float disableFX;
12 | uniform float translucencyMix;
13 | uniform vec2 resolution;
14 | uniform vec2 offsetUV;
15 |
16 | varying vec3 vPos;
17 | varying vec3 vEyeDir;
18 | varying vec3 vLightDir;
19 | varying vec3 vNormal;
20 | varying vec2 vUv;
21 |
22 | float kC = 0.5;
23 | float kL = 0.05;
24 | float kQ = 0.0001;
25 |
26 | float range(float oldValue, float oldMin, float oldMax, float newMin, float newMax) {
27 | float oldRange = oldMax - oldMin;
28 | float newRange = newMax - newMin;
29 | return (((oldValue - oldMin) * newRange) / oldRange) + newMin;
30 | }
31 |
32 | float crange(float oldValue, float oldMin, float oldMax, float newMin, float newMax) {
33 | return clamp(range(oldValue, oldMin, oldMax, newMin, newMax), newMin, newMax);
34 | }
35 |
36 | vec3 rgb2hsv(vec3 c) {
37 | vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
38 | vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
39 | vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
40 |
41 | float d = q.x - min(q.w, q.y);
42 | float e = 1.0e-10;
43 | return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
44 | }
45 |
46 | vec3 hsv2rgb(vec3 c) {
47 | vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
48 | vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
49 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
50 | }
51 |
52 | vec3 mod289(vec3 x) {
53 | return x - floor(x * (1.0 / 289.0)) * 289.0;
54 | }
55 |
56 | vec4 mod289(vec4 x) {
57 | return x - floor(x * (1.0 / 289.0)) * 289.0;
58 | }
59 |
60 | vec4 permute(vec4 x) {
61 | return mod289(((x*34.0)+1.0)*x);
62 | }
63 |
64 | vec4 taylorInvSqrt(vec4 r) {
65 | return 1.79284291400159 - 0.85373472095314 * r;
66 | }
67 |
68 | float snoise(vec3 v) {
69 | const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;
70 | const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
71 |
72 | vec3 i = floor(v + dot(v, C.yyy) );
73 | vec3 x0 = v - i + dot(i, C.xxx) ;
74 |
75 | vec3 g = step(x0.yzx, x0.xyz);
76 | vec3 l = 1.0 - g;
77 | vec3 i1 = min( g.xyz, l.zxy );
78 | vec3 i2 = max( g.xyz, l.zxy );
79 |
80 | vec3 x1 = x0 - i1 + C.xxx;
81 | vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
82 | vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
83 |
84 | i = mod289(i);
85 | vec4 p = permute( permute( permute(
86 | i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
87 | + i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
88 | + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
89 |
90 | float n_ = 0.142857142857; // 1.0/7.0
91 | vec3 ns = n_ * D.wyz - D.xzx;
92 |
93 | vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
94 |
95 | vec4 x_ = floor(j * ns.z);
96 | vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)
97 |
98 | vec4 x = x_ *ns.x + ns.yyyy;
99 | vec4 y = y_ *ns.x + ns.yyyy;
100 | vec4 h = 1.0 - abs(x) - abs(y);
101 |
102 | vec4 b0 = vec4( x.xy, y.xy );
103 | vec4 b1 = vec4( x.zw, y.zw );
104 |
105 | vec4 s0 = floor(b0)*2.0 + 1.0;
106 | vec4 s1 = floor(b1)*2.0 + 1.0;
107 | vec4 sh = -step(h, vec4(0.0));
108 |
109 | vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
110 | vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
111 |
112 | vec3 p0 = vec3(a0.xy,h.x);
113 | vec3 p1 = vec3(a0.zw,h.y);
114 | vec3 p2 = vec3(a1.xy,h.z);
115 | vec3 p3 = vec3(a1.zw,h.w);
116 |
117 | vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
118 | p0 *= norm.x;
119 | p1 *= norm.y;
120 | p2 *= norm.z;
121 | p3 *= norm.w;
122 |
123 | vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
124 | m = m * m;
125 | return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) );
126 | }
127 |
128 | vec3 desaturate(vec3 color, float amount) {
129 | vec3 gray = vec3(dot(vec3(0.2126,0.7152,0.0722), color));
130 | return vec3(mix(color, gray, amount));
131 | }
132 |
133 | vec3 getColor() {
134 | float noise = snoise((vPos * 0.8) + time);
135 | vec3 color = rgb2hsv(lightColor);
136 | color.x += 0.05 * noise;
137 | color.z -= darkness;
138 | color = hsv2rgb(color);
139 | return color;
140 | }
141 |
142 | vec2 getScreenUV() {
143 | return gl_FragCoord.xy / resolution;
144 | }
145 |
146 | float getLum(vec3 color) {
147 | return (color.r + color.g + color.b) / 3.0;
148 | }
149 |
150 | void main() {
151 | vec3 normal = vNormal;
152 |
153 | vec3 diffuse = vec3(1.0);
154 |
155 | vec3 N = normalize(normal);
156 | vec3 L = normalize(vLightDir);
157 | vec3 V = normalize(vEyeDir);
158 |
159 | vec3 lightPosition = vec3(0.0);
160 |
161 | float d = length(lightPosition - vPos);
162 | float lightAttenuation = (1.0 / (kC + kL*d + kQ*d*d)) * strength;
163 |
164 | float thickness = range(length(vPos), 0.0, radius, 1.0, 0.5);
165 | vec3 ltLight = normalize(L + (N * LTDistortion));
166 | float ltDot = clamp(dot(V, -ltLight), 0.0, 1.0) * LTScale;
167 | float LT = lightAttenuation * (ltDot + LTAmbient) * thickness;
168 |
169 | vec3 finalColor = diffuse * getColor() * LT;
170 | vec3 outputColor = finalColor;
171 |
172 | gl_FragColor = vec4(outputColor, 1.0);
173 | }
174 |
--------------------------------------------------------------------------------
/shaders/Gem.vs:
--------------------------------------------------------------------------------
1 | varying vec3 vPos;
2 | varying vec3 vEyeDir;
3 | varying vec3 vLightDir;
4 | varying vec3 vNormal;
5 | varying vec2 vUv;
6 |
7 | void main() {
8 | vec3 lightPosition = vec3(0.0);
9 |
10 | vUv = uv;
11 | vPos = position;
12 | vEyeDir = normalize(cameraPosition - position.xyz);
13 | vLightDir = normalize(lightPosition - position.xyz);
14 | vNormal = normalMatrix * normal;
15 |
16 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
17 | }
18 |
--------------------------------------------------------------------------------
/shaders/Sky.fs:
--------------------------------------------------------------------------------
1 | uniform float time;
2 | uniform float sat;
3 | uniform vec3 color;
4 |
5 | varying vec3 vPos;
6 |
7 | float range(float oldValue, float oldMin, float oldMax, float newMin, float newMax) {
8 | float oldRange = oldMax - oldMin;
9 | float newRange = newMax - newMin;
10 | return (((oldValue - oldMin) * newRange) / oldRange) + newMin;
11 | }
12 |
13 | float crange(float oldValue, float oldMin, float oldMax, float newMin, float newMax) {
14 | return clamp(range(oldValue, oldMin, oldMax, newMin, newMax), newMin, newMax);
15 | }
16 |
17 | // Description : Array and textureless GLSL 2D/3D/4D simplex
18 | // noise functions.
19 | // Author : Ian McEwan, Ashima Arts.
20 | // Maintainer : ijm
21 | // Lastmod : 20110822 (ijm)
22 | // License : Copyright (C) 2011 Ashima Arts. All rights reserved.
23 | // Distributed under the MIT License. See LICENSE file.
24 | // https://github.com/ashima/webgl-noise
25 | //
26 |
27 | vec3 mod289(vec3 x) {
28 | return x - floor(x * (1.0 / 289.0)) * 289.0;
29 | }
30 |
31 | vec4 mod289(vec4 x) {
32 | return x - floor(x * (1.0 / 289.0)) * 289.0;
33 | }
34 |
35 | vec4 permute(vec4 x) {
36 | return mod289(((x*34.0)+1.0)*x);
37 | }
38 |
39 | vec4 taylorInvSqrt(vec4 r) {
40 | return 1.79284291400159 - 0.85373472095314 * r;
41 | }
42 |
43 | float snoise(vec3 v) {
44 | const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;
45 | const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
46 |
47 | vec3 i = floor(v + dot(v, C.yyy) );
48 | vec3 x0 = v - i + dot(i, C.xxx) ;
49 |
50 | vec3 g = step(x0.yzx, x0.xyz);
51 | vec3 l = 1.0 - g;
52 | vec3 i1 = min( g.xyz, l.zxy );
53 | vec3 i2 = max( g.xyz, l.zxy );
54 |
55 | vec3 x1 = x0 - i1 + C.xxx;
56 | vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
57 | vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
58 |
59 | i = mod289(i);
60 | vec4 p = permute( permute( permute(
61 | i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
62 | + i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
63 | + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
64 |
65 | float n_ = 0.142857142857; // 1.0/7.0
66 | vec3 ns = n_ * D.wyz - D.xzx;
67 |
68 | vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
69 |
70 | vec4 x_ = floor(j * ns.z);
71 | vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)
72 |
73 | vec4 x = x_ *ns.x + ns.yyyy;
74 | vec4 y = y_ *ns.x + ns.yyyy;
75 | vec4 h = 1.0 - abs(x) - abs(y);
76 |
77 | vec4 b0 = vec4( x.xy, y.xy );
78 | vec4 b1 = vec4( x.zw, y.zw );
79 |
80 | vec4 s0 = floor(b0)*2.0 + 1.0;
81 | vec4 s1 = floor(b1)*2.0 + 1.0;
82 | vec4 sh = -step(h, vec4(0.0));
83 |
84 | vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
85 | vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
86 |
87 | vec3 p0 = vec3(a0.xy,h.x);
88 | vec3 p1 = vec3(a0.zw,h.y);
89 | vec3 p2 = vec3(a1.xy,h.z);
90 | vec3 p3 = vec3(a1.zw,h.w);
91 |
92 | vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
93 | p0 *= norm.x;
94 | p1 *= norm.y;
95 | p2 *= norm.z;
96 | p3 *= norm.w;
97 |
98 | vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
99 | m = m * m;
100 | return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) );
101 | }
102 |
103 | //float surface(vec3 coord) {
104 | // float n = 0.0;
105 | // n += 1.0 * abs(snoise(coord));
106 | // n += 0.5 * abs(snoise(coord * 2.0));
107 | // n += 0.25 * abs(snoise(coord * 4.0));
108 | // n += 0.125 * abs(snoise(coord * 8.0));
109 | // float rn = 1.0 - n;
110 | // return rn * rn;
111 | //}
112 |
113 | vec3 rgb2hsv(vec3 c) {
114 | vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
115 | vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
116 | vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
117 |
118 | float d = q.x - min(q.w, q.y);
119 | float e = 1.0e-10;
120 | return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
121 | }
122 |
123 | vec3 hsv2rgb(vec3 c) {
124 | vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
125 | vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
126 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
127 | }
128 |
129 | vec3 desaturate(vec3 color, float amount) {
130 | vec3 gray = vec3(dot(vec3(0.2126,0.7152,0.0722), color));
131 | return vec3(mix(color, gray, amount));
132 | }
133 |
134 | vec3 offsetColor(float noise) {
135 | vec3 c = rgb2hsv(color);
136 | c.x += 0.25;
137 | c = hsv2rgb(c);
138 | return c;
139 | }
140 |
141 | void main() {
142 | float fNoise = snoise((vPos * 0.01) + time * 10.0);
143 | float noise = range(fNoise, -1.0, 1.0, 0.0, 1.0);
144 |
145 | vec3 color0 = color;
146 | vec3 color1 = offsetColor(fNoise);
147 |
148 | vec3 finalColor = mix(color0, color1, noise);
149 |
150 | finalColor *= clamp(range(abs(vPos.y), 0.0, 25.0, 1.2, 1.0), 1.0, 15.0);
151 |
152 | finalColor = rgb2hsv(finalColor);
153 | finalColor.z -= range(sat, 0.0, 1.0, 0.0, 0.7);
154 | finalColor = hsv2rgb(finalColor);
155 |
156 | gl_FragColor = vec4(finalColor, 1.0);
157 | }
158 |
--------------------------------------------------------------------------------
/shaders/Sky.vs:
--------------------------------------------------------------------------------
1 | varying vec3 vPos;
2 |
3 | void main() {
4 | vPos = position;
5 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
6 | }
7 |
--------------------------------------------------------------------------------
/shaders/Terrain.fs:
--------------------------------------------------------------------------------
1 | uniform vec3 baseColor;
2 | uniform float transition;
3 | uniform float transHeight;
4 | uniform float transDirection;
5 | uniform vec3 multiplyColor;
6 | uniform vec3 lightPos;
7 | uniform vec3 lightColor;
8 | uniform mat4 modelViewMatrix;
9 |
10 | varying vec3 vViewPosition;
11 | varying vec3 vWorldPos;
12 | varying vec3 vPos;
13 | varying vec2 vUv;
14 | varying float vAlpha;
15 | varying float vSat;
16 |
17 | vec3 rgb2hsv(vec3 c) {
18 | vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
19 | vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
20 | vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
21 |
22 | float d = q.x - min(q.w, q.y);
23 | float e = 1.0e-10;
24 | return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
25 | }
26 |
27 | vec3 hsv2rgb(vec3 c) {
28 | vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
29 | vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
30 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
31 | }
32 |
33 | float range(float oldValue, float oldMin, float oldMax, float newMin, float newMax) {
34 | float oldRange = oldMax - oldMin;
35 | float newRange = newMax - newMin;
36 | return (((oldValue - oldMin) * newRange) / oldRange) + newMin;
37 | }
38 |
39 | float crange(float oldValue, float oldMin, float oldMax, float newMin, float newMax) {
40 | return clamp(range(oldValue, oldMin, oldMax, newMin, newMax), newMin, newMax);
41 | }
42 |
43 | vec3 worldLight(vec3 pos, vec3 vpos) {
44 | vec4 mvPos = modelViewMatrix * vec4(vpos, 1.0);
45 | vec4 worldPosition = viewMatrix * vec4(pos, 1.0);
46 | return worldPosition.xyz - mvPos.xyz;
47 | }
48 |
49 | float transitionMask(vec2 vuv) {
50 | float dist = length(vec2(0.5) - vuv);
51 | float r = range(dist, 0.0, 0.5, 0.0, 1.0);
52 | float a = step(1.0 - r, transition);
53 | float b = step(r, transition);
54 | return mix(a, b, transDirection);
55 | }
56 |
57 | float heightMask(vec2 vuv) {
58 | float dist = length(vec2(0.5) - vuv);
59 | float r = range(dist, 0.0, 0.5, 0.0, 1.0);
60 | float a = 1.0 - smoothstep(transHeight - 0.5, transHeight + 0.5, 1.0 - r);
61 | float b = 1.0 - smoothstep(transHeight - 0.5, transHeight + 0.5, r);
62 |
63 | float height = mix(a, b, transDirection);
64 |
65 | return height;
66 | }
67 |
68 | vec3 getDNormal(vec3 viewPos) {
69 | vec3 dfx = vec3(0.0);
70 | vec3 dfy = vec3(0.0);
71 |
72 | dfx.x = dFdx(viewPos.x);
73 | dfx.y = dFdx(viewPos.y);
74 | dfx.z = dFdx(viewPos.z);
75 |
76 | dfy.x = dFdy(viewPos.x);
77 | dfy.y = dFdy(viewPos.y);
78 | dfy.z = dFdy(viewPos.z);
79 |
80 | return cross(dfx, dfy);
81 | }
82 |
83 | vec3 calculateLight(vec3 worldPos, vec3 n) {
84 | vec3 lPos = worldLight(lightPos, vPos);
85 | float volume = max(dot(normalize(lPos), n), 0.0);
86 |
87 | vec3 color = mix(baseColor, lightColor, volume);
88 | color *= range(volume, 0.0, 1.0, 0.8, 1.0);
89 |
90 | return color;
91 | }
92 |
93 | float getFogAmount() {
94 | vec2 pos = vPos.xz;
95 | return pow(smoothstep(25.0, 35.0, length(pos)), 2.0);
96 | }
97 |
98 | void main() {
99 | vec3 normal = normalize(getDNormal(vViewPosition));
100 |
101 | vec3 terrain = calculateLight(vWorldPos, normal) * multiplyColor;
102 | terrain = rgb2hsv(terrain);
103 | terrain.y += vSat;
104 | terrain = hsv2rgb(terrain);
105 | gl_FragColor = vec4(terrain, 1.0);
106 |
107 | gl_FragColor = mix(gl_FragColor, vec4(0.0), getFogAmount());
108 | gl_FragColor.a *= transitionMask(vUv);
109 |
110 | if (gl_FragColor.a < 0.01) discard;
111 | }
112 |
--------------------------------------------------------------------------------
/shaders/Terrain.vs:
--------------------------------------------------------------------------------
1 | uniform float time;
2 | uniform float transHeight;
3 | uniform float transition;
4 | uniform float transDirection;
5 | uniform sampler2D tTransition;
6 |
7 | varying vec3 vWorldPos;
8 | varying vec3 vViewPosition;
9 | varying vec3 vPos;
10 | varying vec2 vUv;
11 | varying float vAlpha;
12 | varying float vSat;
13 |
14 | float range(float oldValue, float oldMin, float oldMax, float newMin, float newMax) {
15 | float oldRange = oldMax - oldMin;
16 | float newRange = newMax - newMin;
17 | return (((oldValue - oldMin) * newRange) / oldRange) + newMin;
18 | }
19 |
20 | float crange(float oldValue, float oldMin, float oldMax, float newMin, float newMax) {
21 | return clamp(range(oldValue, oldMin, oldMax, newMin, newMax), newMin, newMax);
22 | }
23 |
24 | // Description : Array and textureless GLSL 2D/3D/4D simplex
25 | // noise functions.
26 | // Author : Ian McEwan, Ashima Arts.
27 | // Maintainer : ijm
28 | // Lastmod : 20110822 (ijm)
29 | // License : Copyright (C) 2011 Ashima Arts. All rights reserved.
30 | // Distributed under the MIT License. See LICENSE file.
31 | // https://github.com/ashima/webgl-noise
32 | //
33 |
34 | vec3 mod289(vec3 x) {
35 | return x - floor(x * (1.0 / 289.0)) * 289.0;
36 | }
37 |
38 | vec4 mod289(vec4 x) {
39 | return x - floor(x * (1.0 / 289.0)) * 289.0;
40 | }
41 |
42 | vec4 permute(vec4 x) {
43 | return mod289(((x*34.0)+1.0)*x);
44 | }
45 |
46 | vec4 taylorInvSqrt(vec4 r) {
47 | return 1.79284291400159 - 0.85373472095314 * r;
48 | }
49 |
50 | float snoise(vec3 v) {
51 | const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;
52 | const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
53 |
54 | vec3 i = floor(v + dot(v, C.yyy) );
55 | vec3 x0 = v - i + dot(i, C.xxx) ;
56 |
57 | vec3 g = step(x0.yzx, x0.xyz);
58 | vec3 l = 1.0 - g;
59 | vec3 i1 = min( g.xyz, l.zxy );
60 | vec3 i2 = max( g.xyz, l.zxy );
61 |
62 | vec3 x1 = x0 - i1 + C.xxx;
63 | vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
64 | vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
65 |
66 | i = mod289(i);
67 | vec4 p = permute( permute( permute(
68 | i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
69 | + i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
70 | + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
71 |
72 | float n_ = 0.142857142857; // 1.0/7.0
73 | vec3 ns = n_ * D.wyz - D.xzx;
74 |
75 | vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
76 |
77 | vec4 x_ = floor(j * ns.z);
78 | vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)
79 |
80 | vec4 x = x_ *ns.x + ns.yyyy;
81 | vec4 y = y_ *ns.x + ns.yyyy;
82 | vec4 h = 1.0 - abs(x) - abs(y);
83 |
84 | vec4 b0 = vec4( x.xy, y.xy );
85 | vec4 b1 = vec4( x.zw, y.zw );
86 |
87 | vec4 s0 = floor(b0)*2.0 + 1.0;
88 | vec4 s1 = floor(b1)*2.0 + 1.0;
89 | vec4 sh = -step(h, vec4(0.0));
90 |
91 | vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
92 | vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
93 |
94 | vec3 p0 = vec3(a0.xy,h.x);
95 | vec3 p1 = vec3(a0.zw,h.y);
96 | vec3 p2 = vec3(a1.xy,h.z);
97 | vec3 p3 = vec3(a1.zw,h.w);
98 |
99 | vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
100 | p0 *= norm.x;
101 | p1 *= norm.y;
102 | p2 *= norm.z;
103 | p3 *= norm.w;
104 |
105 | vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
106 | m = m * m;
107 | return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) );
108 | }
109 |
110 | float aastep(float threshold, float value, float buf) {
111 | return smoothstep(threshold - buf, threshold + buf, value);
112 | }
113 |
114 | float transitionMask(vec2 vuv) {
115 | float dist = length(vec2(0.5) - vuv);
116 | float r = range(dist, 0.0, 0.5, 0.0, 1.0);
117 | float a = step(1.0 - r, transition);
118 | float b = step(r, transition);
119 | return mix(a, b, transDirection);
120 | }
121 |
122 | float cubicOut(float t) {
123 | float f = t - 1.0;
124 | return f * f * f + 1.0;
125 | }
126 |
127 | float quarticInOut(float t) {
128 | return t < 0.5
129 | ? +8.0 * pow(t, 4.0)
130 | : -8.0 * pow(t - 1.0, 4.0) + 1.0;
131 | }
132 |
133 | float heightMask(vec2 vuv) {
134 | float dist = length(vec2(0.5) - vuv);
135 | float r = range(dist, 0.0, 0.5, 0.0, 1.0);
136 | float a = 1.0 - smoothstep(transHeight - 0.5, transHeight + 0.5, 1.0 - r);
137 | float b = 1.0 - smoothstep(transHeight - 0.5, transHeight + 0.5, r);
138 |
139 | float height = mix(a, b, transDirection);
140 |
141 | return height;
142 | }
143 |
144 | void main() {
145 | float noise = range(snoise((position * 0.054) + time), -1.0, 1.0, 0.0, 1.0);
146 | noise = 1.0 - aastep(0.3, noise, 0.4);
147 |
148 | vAlpha = transitionMask(uv);
149 |
150 | float posLen = length(position);
151 | float height = range(posLen, 5.0, 30.0, 0.2, 20.0);
152 |
153 | float raise = height * noise;
154 | raise *= crange(posLen, 5.0, 10.0, 0.2, 1.0);
155 |
156 | vec3 pos = position;
157 | pos.y += raise * heightMask(uv);
158 |
159 | vSat = crange(pos.y, 0.0, 6.0, 0.0, 0.1);
160 |
161 | vec4 mvPosition = modelViewMatrix * vec4(pos, 1.0);
162 | vViewPosition = -mvPosition.xyz;
163 | vWorldPos = (vec4(pos, 1.0) * modelMatrix).xyz;
164 | vPos = pos;
165 | vUv = uv;
166 | gl_Position = projectionMatrix * mvPosition;
167 | }
168 |
--------------------------------------------------------------------------------