├── AFrameDemo.html ├── AFrameStarter.html ├── BufferGeometry-Shader.html ├── FBM-Triangle-Shredder.html ├── FBM-Triangle-Shredder3.html ├── Fire-and-Water.html ├── Geometry.html ├── GeometryTerrain.html ├── Hierarchy-Rotation.html ├── Jungle-Birds.html ├── Misty.html ├── Project1-Lighting.html ├── Project2a-Multiple-Objects.html ├── Project2b-Simple-Controls.html ├── README.md ├── Shaders-FractalTorus.html ├── Shaders-Torus.html ├── Starbucks.html ├── Volumetric.html ├── WebAssets ├── audio │ ├── 04 Cabin Sessions (ft_ Exmag & Benny Bloom).mp3 │ ├── 20Hz-20kHz-Sweep.mp3 │ ├── Home.mp3 │ ├── JaiPaul.mp3 │ ├── SlowBurn.mp3 │ ├── ThoseDays.mp3 │ └── the one.m4a ├── css │ ├── font-awesome.min.css │ └── main.css ├── fonts │ ├── FontAwesome.otf │ ├── SharpSansNo1Medium_Regular.json │ ├── SharpSansNo2Bold_Regular.json │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ ├── fontawesome-webfont.woff2 │ └── helvetiker_bold.typeface.json ├── images │ ├── 1.png │ ├── 10.png │ ├── 11.png │ ├── 2.png │ ├── 3.png │ ├── 360Desert.jpg │ ├── 360Light.jpg │ ├── 4.png │ ├── 5.png │ ├── 6.png │ ├── 7.png │ ├── 8.png │ ├── 9.png │ ├── bg.jpg │ ├── favicon.ico │ ├── fb-art.png │ ├── fb.png │ ├── gh.png │ ├── hierarchy.png │ ├── starbucks.png │ └── uw_logo_white.png └── js │ ├── jquery.min.js │ ├── jquery.poptrox.min.js │ ├── main.js │ └── skel.min.js ├── cgpp2018.js ├── cgppSchedule.html ├── fullcalendar.css ├── fullcalendar.js ├── index.html ├── js ├── ColorTracker.js ├── CopyShader.js ├── Detector.js ├── EffectComposer.js ├── ExplodeModifier.js ├── GeometryWorker.js ├── HeaderText.js ├── LuminosityHighPassShader.js ├── Mirror.js ├── MobileAndTabletCheck.js ├── OBJLoader.js ├── OrbitControls.js ├── RenderPass.js ├── ShaderPass.js ├── SubdivisionModifier.js ├── THREE.MeshLine.js ├── TessellateModifier.js ├── UnrealBloomPass.js ├── WaterShader.js ├── dat.gui.min.js ├── noise.js ├── perlin.js ├── simplexnoise.js ├── stats.min.js └── three.js ├── lib ├── jquery-ui.min.js ├── jquery.min.js └── moment.min.js ├── main.css ├── server2.py ├── server3.py ├── textures ├── Thumbs.db ├── lava │ ├── Thumbs.db │ └── lavatile.jpg ├── starbucks │ ├── Thumbs.db │ ├── bumpmap.jpg │ ├── sb.obj │ ├── sb3.jpg │ └── wood.jpg └── waternormals.jpg ├── webgl-modifier-tessellation.html └── week1_w17 ├── AudioBasic.html ├── AudioStarterKit.html └── AudioStarterKit2.html /AFrameDemo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CGPP VR HomePage 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 29 | 30 | 31 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /AFrameStarter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CGPP VR HomePage 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 37 | 38 | 39 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /BufferGeometry-Shader.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | three.js webgl - raw shader 5 | 6 | 7 | 14 | 15 | 16 | 17 | 18 | 19 | 40 | 41 | 59 | 60 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /Fire-and-Water.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Fire and Water 5 | 6 | 42 | 43 | 44 | 45 |
Lee Polla - Made Something Cool
46 |
47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 69 | 70 | 71 | 72 | 100 | 101 | 102 | 198 | 199 | 200 | 201 | 202 | -------------------------------------------------------------------------------- /Geometry.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Lighting 4 | 9 | 10 | 11 | 12 | 13 | 14 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /GeometryTerrain.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Lighting 4 | 9 | 10 | 11 | 12 | 13 | 14 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /Hierarchy-Rotation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hierarchy Rotation 5 | 6 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 232 | 233 | 234 | -------------------------------------------------------------------------------- /Jungle-Birds.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Jungle Birds 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
CGPP Swoopin and Loopin
13 |
14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 59 | 60 | 79 | 80 | 81 | 301 | 302 | 303 | 304 | -------------------------------------------------------------------------------- /Misty.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | FBM Vertex Shader 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
CGPP FBM Triangle Shredder
13 |
14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 64 | 65 | 92 | 93 | 94 | 95 | 304 | 305 | 306 | 307 | -------------------------------------------------------------------------------- /Project1-Lighting.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Lighting 4 | 9 | 10 | 11 | 12 | 13 | 85 | 86 | -------------------------------------------------------------------------------- /Project2a-Multiple-Objects.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Multiple Objects 4 | 9 | 10 | 11 | 12 | 13 | 71 | 72 | -------------------------------------------------------------------------------- /Project2b-Simple-Controls.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Simple Controls 4 | 9 | 10 | 11 | 12 | 13 | 96 | 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Demo and Tutorial Projects 2 | 3 | Welcome to the CGPP code repository! 4 | 5 | Here you will find projects made with [three.js](https://threejs.org/) 6 | 7 | Many more examples like these can be found [here](https://threejs.org/examples) 8 | 9 | # A few good beginner tutorials: 10 | 11 | [Create a rotating box and load a model file](https://dinosaurscode.xyz/tutorials/2016/07/15/three-js-tutorial-for-beginners/) 12 | 13 | [A nice intro to threejs](https://aerotwist.com/tutorials/getting-started-with-three-js/) 14 | 15 | [Interactive site demoing 3D graphics concepts](http://www.dimroc.com/reveal.js-threejs/) 16 | 17 | 18 | # Cool personal sites, blogs, and twitter accounts: 19 | 20 | [Amanda Ghassaei](http://www.amandaghassaei.com/) 21 | 22 | [Jaume Sanchez](https://www.clicktorelease.com/) 23 | 24 | [David Li](http://david.li) 25 | 26 | [Cabbibo](http://cabbi.bo/) 27 | 28 | [Steve Wittens](https://acko.net/) 29 | 30 | [AlteredQualia](http://alteredqualia.com/) 31 | 32 | [Evan Wallace](http://madebyevan.com/) 33 | 34 | [Benedikt Bitterli](https://benedikt-bitterli.me/) 35 | 36 | [Jessica Mak](https://twitter.com/mango_lychee) 37 | 38 | [Inigo Quilez](http://www.iquilezles.org/) 39 | 40 | [Paul Lewis](https://aerotwist.com) 41 | 42 | [Samsy](http://samsy.ninja/) 43 | 44 | [George Corney](https://twitter.com/haxiomic) 45 | 46 | [Daniel Johnson](http://www.hexahedria.com/experiments/) 47 | 48 | [Ricardo Cabello](http://mrdoob.com) 49 | 50 | [Florian Bosch](https://twitter.com/pyalot) 51 | 52 | [Justin Windle](https://soulwire.co.uk/) 53 | 54 | [Adam Harley](http://scs.ryerson.ca/~aharley/vis/conv/) 55 | 56 | [Jonas Degrave](https://317070.github.io/) 57 | 58 | [Chistopher Morre](http://christopheremoore.net/home.lua) 59 | 60 | [Felix Woitzel](https://twitter.com/flexi23) 61 | 62 | 63 | # Advanced (Math and Graphics API heavy) resources: 64 | 65 | [GPU Gems 3](https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_pref01.html) 66 | 67 | [The Book of Shaders (Walkthrough of fragment shaders)](https://thebookofshaders.com/) 68 | 69 | [Udacity Course](https://www.udacity.com/course/interactive-3d-graphics--cs291) 70 | 71 | [Inigo Quilez Articles](http://www.iquilezles.org/www/index.htm) 72 | 73 | 74 | # Communities: 75 | 76 | [ShaderToy](https://www.shadertoy.com/) 77 | 78 | [OpenProcessing](https://www.openprocessing.org/) 79 | 80 | -------------------------------------------------------------------------------- /Shaders-FractalTorus.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | LSD Shader 4 | 8 | 9 | 10 | 11 | 12 | 32 | 33 | 87 | 191 | 192 | -------------------------------------------------------------------------------- /Shaders-Torus.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Shaders 5 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 40 | 41 | 70 | 71 | 147 | 148 | -------------------------------------------------------------------------------- /Starbucks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Starbucks threejs Visualization 4 | 8 | 9 | 10 | 11 | 12 | 13 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /Volumetric.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Volumetric Shader 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WebAssets/audio/04 Cabin Sessions (ft_ Exmag & Benny Bloom).mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/audio/04 Cabin Sessions (ft_ Exmag & Benny Bloom).mp3 -------------------------------------------------------------------------------- /WebAssets/audio/20Hz-20kHz-Sweep.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/audio/20Hz-20kHz-Sweep.mp3 -------------------------------------------------------------------------------- /WebAssets/audio/Home.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/audio/Home.mp3 -------------------------------------------------------------------------------- /WebAssets/audio/JaiPaul.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/audio/JaiPaul.mp3 -------------------------------------------------------------------------------- /WebAssets/audio/SlowBurn.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/audio/SlowBurn.mp3 -------------------------------------------------------------------------------- /WebAssets/audio/ThoseDays.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/audio/ThoseDays.mp3 -------------------------------------------------------------------------------- /WebAssets/audio/the one.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/audio/the one.m4a -------------------------------------------------------------------------------- /WebAssets/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /WebAssets/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /WebAssets/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /WebAssets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /WebAssets/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /WebAssets/images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/1.png -------------------------------------------------------------------------------- /WebAssets/images/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/10.png -------------------------------------------------------------------------------- /WebAssets/images/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/11.png -------------------------------------------------------------------------------- /WebAssets/images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/2.png -------------------------------------------------------------------------------- /WebAssets/images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/3.png -------------------------------------------------------------------------------- /WebAssets/images/360Desert.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/360Desert.jpg -------------------------------------------------------------------------------- /WebAssets/images/360Light.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/360Light.jpg -------------------------------------------------------------------------------- /WebAssets/images/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/4.png -------------------------------------------------------------------------------- /WebAssets/images/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/5.png -------------------------------------------------------------------------------- /WebAssets/images/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/6.png -------------------------------------------------------------------------------- /WebAssets/images/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/7.png -------------------------------------------------------------------------------- /WebAssets/images/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/8.png -------------------------------------------------------------------------------- /WebAssets/images/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/9.png -------------------------------------------------------------------------------- /WebAssets/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/bg.jpg -------------------------------------------------------------------------------- /WebAssets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/favicon.ico -------------------------------------------------------------------------------- /WebAssets/images/fb-art.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/fb-art.png -------------------------------------------------------------------------------- /WebAssets/images/fb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/fb.png -------------------------------------------------------------------------------- /WebAssets/images/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/gh.png -------------------------------------------------------------------------------- /WebAssets/images/hierarchy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/hierarchy.png -------------------------------------------------------------------------------- /WebAssets/images/starbucks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/starbucks.png -------------------------------------------------------------------------------- /WebAssets/images/uw_logo_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/WebAssets/images/uw_logo_white.png -------------------------------------------------------------------------------- /WebAssets/js/jquery.poptrox.min.js: -------------------------------------------------------------------------------- 1 | /* jquery.poptrox.js v2.5.2-dev | (c) n33 | n33.co | MIT licensed */ 2 | !function(e){e.fn.poptrox_disableSelection=function(){return e(this).css("user-select","none").css("-khtml-user-select","none").css("-moz-user-select","none").css("-o-user-select","none").css("-webkit-user-select","none")},e.fn.poptrox=function(o){function t(){i=e(window).width(),s=e(window).height()+r.windowHeightPad;var o=Math.abs(x.width()-x.outerWidth()),t=Math.abs(x.height()-x.outerHeight()),p=(w.width(),w.height(),i-2*r.windowMargin-o),n=s-2*r.windowMargin-t;x.css("min-width",r.popupWidth).css("min-height",r.popupHeight),v.children().css("max-width",p).css("max-height",n)}if(0==this.length)return e(this);if(this.length>1){for(var p=0;p'),u=e(window),d=[],h=0,g=!1,f=new Array;r.usePopupLoader||(r.popupLoaderSelector=null),r.usePopupCloser||(r.popupCloserSelector=null),r.usePopupCaption||(r.popupCaptionSelector=null),r.usePopupNav||(r.popupNavPreviousSelector=null,r.popupNavNextSelector=null);var x;x=e(r.popupSelector?r.popupSelector:'
'+(r.popupLoaderSelector?'
'+r.popupLoaderText+"
":"")+'
'+(r.popupCaptionSelector?'
':"")+(r.popupCloserSelector?''+r.popupCloserText+"":"")+(r.popupNavPreviousSelector?'':"")+(r.popupNavNextSelector?'':"")+"
");var v=x.find(".pic"),w=e(),b=x.find(r.popupLoaderSelector),m=x.find(r.popupCaptionSelector),C=x.find(r.popupCloserSelector),y=x.find(r.popupNavNextSelector),S=x.find(r.popupNavPreviousSelector),P=y.add(S);if(r.usePopupDefaultStyling&&(x.css("background",r.popupBackgroundColor).css("color",r.popupTextColor).css("padding",r.popupPadding+"px"),m.length>0&&(x.css("padding-bottom",r.popupCaptionHeight+"px"),m.css("position","absolute").css("left","0").css("bottom","0").css("width","100%").css("text-align","center").css("height",r.popupCaptionHeight+"px").css("line-height",r.popupCaptionHeight+"px"),r.popupCaptionTextSize&&m.css("font-size",popupCaptionTextSize)),C.length>0&&C.html(r.popupCloserText).css("font-size",r.popupCloserTextSize).css("background",r.popupCloserBackgroundColor).css("color",r.popupCloserTextColor).css("display","block").css("width","40px").css("height","40px").css("line-height","40px").css("text-align","center").css("position","absolute").css("text-decoration","none").css("outline","0").css("top","0").css("right","-40px"),b.length>0&&b.html("").css("position","relative").css("font-size",r.popupLoaderTextSize).on("startSpinning",function(o){var t=e("
"+r.popupLoaderText+"
");t.css("height",Math.floor(r.popupHeight/2)+"px").css("overflow","hidden").css("line-height",Math.floor(r.popupHeight/2)+"px").css("text-align","center").css("margin-top",Math.floor((x.height()-t.height()+(m.length>0?m.height():0))/2)).css("color",r.popupTextColor?r.popupTextColor:"").on("xfin",function(){t.fadeTo(300,.5,function(){t.trigger("xfout")})}).on("xfout",function(){t.fadeTo(300,.05,function(){t.trigger("xfin")})}).trigger("xfin"),b.append(t)}).on("stopSpinning",function(e){var o=b.find("div");o.remove()}),2==P.length)){P.css("font-size","75px").css("text-align","center").css("color","#fff").css("text-shadow","none").css("height","100%").css("position","absolute").css("top","0").css("opacity","0.35").css("cursor","pointer").css("box-shadow","inset 0px 0px 10px 0px rgba(0,0,0,0)").poptrox_disableSelection();var k,T;r.usePopupEasyClose?(k="100px",T="100px"):(k="75%",T="25%"),y.css("right","0").css("width",k).html('
>
'),S.css("left","0").css("width",T).html('
<
')}return u.on("resize orientationchange",function(){t()}),m.on("update",function(e,o){o&&0!=o.length||(o=r.popupBlankCaptionText),m.html(o)}),C.css("cursor","pointer").on("click",function(e){return e.preventDefault(),e.stopPropagation(),x.trigger("poptrox_close"),!0}),y.on("click",function(e){e.stopPropagation(),e.preventDefault(),x.trigger("poptrox_next")}),S.on("click",function(e){e.stopPropagation(),e.preventDefault(),x.trigger("poptrox_previous")}),l.css("position","fixed").css("left",0).css("top",0).css("z-index",r.baseZIndex).css("width","100%").css("height","100%").css("text-align","center").css("cursor","pointer").appendTo(r.parent).prepend('
').append('
').hide().on("touchmove",function(e){return!1}).on("click",function(e){e.preventDefault(),e.stopPropagation(),x.trigger("poptrox_close")}),x.css("display","inline-block").css("vertical-align","middle").css("position","relative").css("z-index",1).css("cursor","auto").appendTo(l).hide().on("poptrox_next",function(){var e=h+1;e>=d.length&&(e=0),x.trigger("poptrox_switch",[e])}).on("poptrox_previous",function(){var e=h-1;0>e&&(e=d.length-1),x.trigger("poptrox_switch",[e])}).on("poptrox_reset",function(){t(),x.data("width",r.popupWidth).data("height",r.popupHeight),b.hide().trigger("stopSpinning"),m.hide(),C.hide(),P.hide(),v.hide(),w.attr("src","").detach()}).on("poptrox_open",function(e,o){return g?!0:(g=!0,r.useBodyOverflow&&a.css("overflow","hidden"),r.onPopupOpen&&r.onPopupOpen(),x.addClass("loading"),void l.fadeTo(r.fadeSpeed,1,function(){x.trigger("poptrox_switch",[o,!0])}))}).on("poptrox_switch",function(o,p,i){var s;if(!i&&g)return!0;if(g=!0,x.addClass("loading").css("width",x.data("width")).css("height",x.data("height")),m.hide(),w.attr("src")&&w.attr("src",""),w.detach(),s=d[p],w=s.object,w.off("load"),v.css("text-indent","-9999px").show().append(w),"ajax"==s.type?e.get(s.src,function(e){w.html(e),w.trigger("load")}):w.attr("src",s.src),"image"!=s.type){var n,a;n=s.width,a=s.height,"%"==n.slice(-1)&&(n=parseInt(n.substring(0,n.length-1))/100*u.width()),"%"==a.slice(-1)&&(a=parseInt(a.substring(0,a.length-1))/100*u.height()),w.css("position","relative").css("outline","0").css("z-index",r.baseZIndex+100).width(n).height(a)}b.trigger("startSpinning").fadeIn(300),x.show(),r.popupIsFixed?(x.removeClass("loading").width(r.popupWidth).height(r.popupHeight),w.load(function(){w.off("load"),b.hide().trigger("stopSpinning"),m.trigger("update",[s.captionText]).fadeIn(r.fadeSpeed),C.fadeIn(r.fadeSpeed),v.css("text-indent",0).hide().fadeIn(r.fadeSpeed,function(){g=!1}),h=p,P.fadeIn(r.fadeSpeed)})):w.load(function(){t(),w.off("load"),b.hide().trigger("stopSpinning");var e=w.width(),o=w.height(),i=function(){m.trigger("update",[s.captionText]).fadeIn(r.fadeSpeed),C.fadeIn(r.fadeSpeed),v.css("text-indent",0).hide().fadeIn(r.fadeSpeed,function(){g=!1}),h=p,P.fadeIn(r.fadeSpeed),x.removeClass("loading").data("width",e).data("height",o).css("width","auto").css("height","auto")};e==x.data("width")&&o==x.data("height")?i():x.animate({width:e,height:o},r.popupSpeed,"swing",i)}),"image"!=s.type&&w.trigger("load")}).on("poptrox_close",function(){return g&&!r.usePopupForceClose?!0:(g=!0,x.hide().trigger("poptrox_reset"),r.onPopupClose&&r.onPopupClose(),void l.fadeOut(r.fadeSpeed,function(){r.useBodyOverflow&&a.css("overflow","auto"),g=!1}))}).trigger("poptrox_reset"),r.usePopupEasyClose?(m.on("click","a",function(e){e.stopPropagation()}),x.css("cursor","pointer").on("click",function(e){e.stopPropagation(),e.preventDefault(),x.trigger("poptrox_close")})):x.on("click",function(e){e.stopPropagation()}),u.keydown(function(e){if(x.is(":visible"))switch(e.keyCode){case 37:case 32:if(r.usePopupNav)return x.trigger("poptrox_previous"),!1;break;case 39:if(r.usePopupNav)return x.trigger("poptrox_next"),!1;break;case 27:return x.trigger("poptrox_close"),!1}}),n.find(r.selector).each(function(o){var t,p,i=e(this),s=i.find("img"),n=i.data("poptrox");if("ignore"!=n&&i.attr("href")){if(t={src:i.attr("href"),captionText:s.attr("title"),width:null,height:null,type:null,object:null,options:null},r.caption){if("function"==typeof r.caption)c=r.caption(i);else if("selector"in r.caption){var a;a=i.find(r.caption.selector),"attribute"in r.caption?c=a.attr(r.caption.attribute):(c=a.html(),r.caption.remove===!0&&a.remove())}}else c=s.attr("title");if(t.captionText=c,n){var l=n.split(",");0 in l&&(t.type=l[0]),1 in l&&(p=l[1].match(/([0-9%]+)x([0-9%]+)/),p&&3==p.length&&(t.width=p[1],t.height=p[2])),2 in l&&(t.options=l[2])}if(!t.type)switch(p=t.src.match(/\/\/([a-z0-9\.]+)\/.*/),(!p||p.length<2)&&(p=[!1]),p[1]){case"api.soundcloud.com":t.type="soundcloud";break;case"youtu.be":t.type="youtube";break;case"vimeo.com":t.type="vimeo";break;case"wistia.net":t.type="wistia";break;case"bcove.me":t.type="bcove";break;default:t.type="image"}switch(p=t.src.match(/\/\/[a-z0-9\.]+\/(.*)/),t.type){case"iframe":t.object=e(''),t.object.on("click",function(e){e.stopPropagation()}).css("cursor","auto"),t.width&&t.height||(t.width=""+(window.innerWidth*0.8),t.height=""+(window.innerHeight*0.7));break;case"ajax":t.object=e('
'),t.object.on("click",function(e){e.stopPropagation()}).css("cursor","auto").css("overflow","auto"),t.width&&t.height||(t.width="600",t.height="400");break;case"soundcloud":t.object=e(''),t.src="//w.soundcloud.com/player/?url="+escape(t.src)+(t.options?"&"+t.options:""),t.width="600",t.height="166";break;case"youtube":t.object=e(''),t.src="//www.youtube.com/embed/"+p[1]+(t.options?"?"+t.options:""),t.width&&t.height||(t.width="800",t.height="480");break;case"vimeo":t.object=e(''),t.src="//player.vimeo.com/video/"+p[1]+(t.options?"?"+t.options:""),t.width&&t.height||(t.width="800",t.height="480");break;case"wistia":t.object=e(''),t.src="//fast.wistia.net/"+p[1]+(t.options?"?"+t.options:""),t.width&&t.height||(t.width="800",t.height="480");break;case"bcove":t.object=e(''),t.src="//bcove.me/"+p[1]+(t.options?"?"+t.options:""),t.width&&t.height||(t.width="640",t.height="360");break;default:if(t.object=e(''),r.preload){var p=document.createElement("img");p.src=t.src,f.push(p)}t.width=i.attr("width"),t.height=i.attr("height")}"file:"==window.location.protocol&&t.src.match(/^\/\//)&&(t.src="http:"+t.src),d.push(t),s.removeAttr("title"),i.removeAttr("href").css("cursor","pointer").css("outline",0).on("click",function(e){e.preventDefault(),e.stopPropagation(),x.trigger("poptrox_open",[o])})}}),n.prop("_poptrox",r),n}}(jQuery); 3 | -------------------------------------------------------------------------------- /WebAssets/js/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | Visualize by TEMPLATED 3 | templated.co @templatedco 4 | Released for free under the Creative Commons Attribution 3.0 license (templated.co/license) 5 | */ 6 | 7 | function growDiv() { 8 | var growDiv = document.getElementById('grow'); 9 | if (growDiv.clientHeight) { 10 | growDiv.style.height = 0; 11 | } else { 12 | var wrapper = document.querySelector('.measuringWrapper'); 13 | growDiv.style.height = wrapper.clientHeight + "px"; 14 | } 15 | //document.getElementById("more-button").value=document.getElementById("more-button").value=='Read more'?'Read less':'Read more'; 16 | } 17 | 18 | $(function() { 19 | 20 | // Vars. 21 | var $window = $(window), 22 | $body = $('body'), 23 | $wrapper = $('#wrapper'); 24 | $viewer = $('#viewer'); 25 | 26 | // Breakpoints. 27 | skel.breakpoints({ 28 | xlarge: '(max-width: 1680px)', 29 | large: '(max-width: 1280px)', 30 | medium: '(max-width: 980px)', 31 | small: '(max-width: 736px)', 32 | xsmall: '(max-width: 480px)' 33 | }); 34 | 35 | // Disable animations/transitions until everything's loaded. 36 | $body.addClass('is-loading'); 37 | 38 | $window.on('load', function() { 39 | $body.removeClass('is-loading'); 40 | }); 41 | 42 | 43 | 44 | // Poptrox. 45 | $window.on('load', function() { 46 | /* 47 | if( navigator.userAgent.match(/Android/i) 48 | || navigator.userAgent.match(/webOS/i) 49 | || navigator.userAgent.match(/iPhone/i) 50 | || navigator.userAgent.match(/iPod/i) 51 | || navigator.userAgent.match(/BlackBerry/i) 52 | || navigator.userAgent.match(/Windows Phone/i) 53 | ) 54 | { 55 | console.log("mobile"); 56 | window.open(this.href); 57 | } else { 58 | console.log("not mobile"); 59 | } 60 | */ 61 | //window.open("https://www.apple.com"); 62 | //console.log("open it !"); 63 | $('.thumbnails').poptrox({ 64 | //window.open(this.href); 65 | onPopupClose: function() { $body.removeClass('is-covered'); }, 66 | onPopupOpen: function() { $body.addClass('is-covered'); }, 67 | baseZIndex: 10001, 68 | useBodyOverflow: false, 69 | usePopupEasyClose: true, 70 | overlayColor: '#000000', 71 | overlayOpacity: 0.75, 72 | usePopupCloser: false, 73 | popupLoaderText: 'Loading...', 74 | fadeSpeed: 400, 75 | popupWidth: window.innerWidth*0.8, 76 | popupHeight: window.innerHeight*0.7, 77 | usePopupDefaultStyling: false, 78 | windowMargin: (skel.breakpoint('small').active ? 5 : 50) 79 | }); 80 | 81 | 82 | }); 83 | 84 | }); -------------------------------------------------------------------------------- /WebAssets/js/skel.min.js: -------------------------------------------------------------------------------- 1 | /* skel.js v3.0.0 | (c) n33 | skel.io | MIT licensed */ 2 | var skel=function(){"use strict";var t={breakpointIds:null,events:{},isInit:!1,obj:{attachments:{},breakpoints:{},head:null,states:{}},sd:"/",state:null,stateHandlers:{},stateId:"",vars:{},DOMReady:null,indexOf:null,isArray:null,iterate:null,matchesMedia:null,extend:function(e,n){t.iterate(n,function(i){t.isArray(n[i])?(t.isArray(e[i])||(e[i]=[]),t.extend(e[i],n[i])):"object"==typeof n[i]?("object"!=typeof e[i]&&(e[i]={}),t.extend(e[i],n[i])):e[i]=n[i]})},newStyle:function(t){var e=document.createElement("style");return e.type="text/css",e.innerHTML=t,e},_canUse:null,canUse:function(e){t._canUse||(t._canUse=document.createElement("div"));var n=t._canUse.style,i=e.charAt(0).toUpperCase()+e.slice(1);return e in n||"Moz"+i in n||"Webkit"+i in n||"O"+i in n||"ms"+i in n},on:function(e,n){var i=e.split(/[\s]+/);return t.iterate(i,function(e){var a=i[e];if(t.isInit){if("init"==a)return void n();if("change"==a)n();else{var r=a.charAt(0);if("+"==r||"!"==r){var o=a.substring(1);if(o in t.obj.breakpoints)if("+"==r&&t.obj.breakpoints[o].active)n();else if("!"==r&&!t.obj.breakpoints[o].active)return void n()}}}t.events[a]||(t.events[a]=[]),t.events[a].push(n)}),t},trigger:function(e){return t.events[e]&&0!=t.events[e].length?(t.iterate(t.events[e],function(n){t.events[e][n]()}),t):void 0},breakpoint:function(e){return t.obj.breakpoints[e]},breakpoints:function(e){function n(t,e){this.name=this.id=t,this.media=e,this.active=!1,this.wasActive=!1}return n.prototype.matches=function(){return t.matchesMedia(this.media)},n.prototype.sync=function(){this.wasActive=this.active,this.active=this.matches()},t.iterate(e,function(i){t.obj.breakpoints[i]=new n(i,e[i])}),window.setTimeout(function(){t.poll()},0),t},addStateHandler:function(e,n){t.stateHandlers[e]=n},callStateHandler:function(e){var n=t.stateHandlers[e]();t.iterate(n,function(e){t.state.attachments.push(n[e])})},changeState:function(e){t.iterate(t.obj.breakpoints,function(e){t.obj.breakpoints[e].sync()}),t.vars.lastStateId=t.stateId,t.stateId=e,t.breakpointIds=t.stateId===t.sd?[]:t.stateId.substring(1).split(t.sd),t.obj.states[t.stateId]?t.state=t.obj.states[t.stateId]:(t.obj.states[t.stateId]={attachments:[]},t.state=t.obj.states[t.stateId],t.iterate(t.stateHandlers,t.callStateHandler)),t.detachAll(t.state.attachments),t.attachAll(t.state.attachments),t.vars.stateId=t.stateId,t.vars.state=t.state,t.trigger("change"),t.iterate(t.obj.breakpoints,function(e){t.obj.breakpoints[e].active?t.obj.breakpoints[e].wasActive||t.trigger("+"+e):t.obj.breakpoints[e].wasActive&&t.trigger("-"+e)})},generateStateConfig:function(e,n){var i={};return t.extend(i,e),t.iterate(t.breakpointIds,function(e){t.extend(i,n[t.breakpointIds[e]])}),i},getStateId:function(){var e="";return t.iterate(t.obj.breakpoints,function(n){var i=t.obj.breakpoints[n];i.matches()&&(e+=t.sd+i.id)}),e},poll:function(){var e="";e=t.getStateId(),""===e&&(e=t.sd),e!==t.stateId&&t.changeState(e)},_attach:null,attach:function(e){var n=t.obj.head,i=e.element;return i.parentNode&&i.parentNode.tagName?!1:(t._attach||(t._attach=n.firstChild),n.insertBefore(i,t._attach.nextSibling),e.permanent&&(t._attach=i),!0)},attachAll:function(e){var n=[];t.iterate(e,function(t){n[e[t].priority]||(n[e[t].priority]=[]),n[e[t].priority].push(e[t])}),n.reverse(),t.iterate(n,function(e){t.iterate(n[e],function(i){t.attach(n[e][i])})})},detach:function(t){var e=t.element;return t.permanent||!e.parentNode||e.parentNode&&!e.parentNode.tagName?!1:(e.parentNode.removeChild(e),!0)},detachAll:function(e){var n={};t.iterate(e,function(t){n[e[t].id]=!0}),t.iterate(t.obj.attachments,function(e){e in n||t.detach(t.obj.attachments[e])})},attachment:function(e){return e in t.obj.attachments?t.obj.attachments[e]:null},newAttachment:function(e,n,i,a){return t.obj.attachments[e]={id:e,element:n,priority:i,permanent:a}},init:function(){t.initMethods(),t.initVars(),t.initEvents(),t.obj.head=document.getElementsByTagName("head")[0],t.isInit=!0,t.trigger("init")},initEvents:function(){t.on("resize",function(){t.poll()}),t.on("orientationChange",function(){t.poll()}),t.DOMReady(function(){t.trigger("ready")}),window.onload&&t.on("load",window.onload),window.onload=function(){t.trigger("load")},window.onresize&&t.on("resize",window.onresize),window.onresize=function(){t.trigger("resize")},window.onorientationchange&&t.on("orientationChange",window.onorientationchange),window.onorientationchange=function(){t.trigger("orientationChange")}},initMethods:function(){document.addEventListener?!function(e,n){t.DOMReady=n()}("domready",function(){function t(t){for(r=1;t=n.shift();)t()}var e,n=[],i=document,a="DOMContentLoaded",r=/^loaded|^c/.test(i.readyState);return i.addEventListener(a,e=function(){i.removeEventListener(a,e),t()}),function(t){r?t():n.push(t)}}):!function(e,n){t.DOMReady=n()}("domready",function(t){function e(t){for(h=1;t=i.shift();)t()}var n,i=[],a=!1,r=document,o=r.documentElement,s=o.doScroll,c="DOMContentLoaded",d="addEventListener",u="onreadystatechange",l="readyState",f=s?/^loaded|^c/:/^loaded|c/,h=f.test(r[l]);return r[d]&&r[d](c,n=function(){r.removeEventListener(c,n,a),e()},a),s&&r.attachEvent(u,n=function(){/^c/.test(r[l])&&(r.detachEvent(u,n),e())}),t=s?function(e){self!=top?h?e():i.push(e):function(){try{o.doScroll("left")}catch(n){return setTimeout(function(){t(e)},50)}e()}()}:function(t){h?t():i.push(t)}}),Array.prototype.indexOf?t.indexOf=function(t,e){return t.indexOf(e)}:t.indexOf=function(t,e){if("string"==typeof t)return t.indexOf(e);var n,i,a=e?e:0;if(!this)throw new TypeError;if(i=this.length,0===i||a>=i)return-1;for(0>a&&(a=i-Math.abs(a)),n=a;i>n;n++)if(this[n]===t)return n;return-1},Array.isArray?t.isArray=function(t){return Array.isArray(t)}:t.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)},Object.keys?t.iterate=function(t,e){if(!t)return[];var n,i=Object.keys(t);for(n=0;i[n]&&e(i[n],t[i[n]])!==!1;n++);}:t.iterate=function(t,e){if(!t)return[];var n;for(n in t)if(Object.prototype.hasOwnProperty.call(t,n)&&e(n,t[n])===!1)break},window.matchMedia?t.matchesMedia=function(t){return""==t?!0:window.matchMedia(t).matches}:window.styleMedia||window.media?t.matchesMedia=function(t){if(""==t)return!0;var e=window.styleMedia||window.media;return e.matchMedium(t||"all")}:window.getComputedStyle?t.matchesMedia=function(t){if(""==t)return!0;var e=document.createElement("style"),n=document.getElementsByTagName("script")[0],i=null;e.type="text/css",e.id="matchmediajs-test",n.parentNode.insertBefore(e,n),i="getComputedStyle"in window&&window.getComputedStyle(e,null)||e.currentStyle;var a="@media "+t+"{ #matchmediajs-test { width: 1px; } }";return e.styleSheet?e.styleSheet.cssText=a:e.textContent=a,"1px"===i.width}:t.matchesMedia=function(t){if(""==t)return!0;var e,n,i,a,r={"min-width":null,"max-width":null},o=!1;for(i=t.split(/\s+and\s+/),e=0;er["max-width"]||null!==r["min-height"]&&cr["max-height"]?!1:!0},navigator.userAgent.match(/MSIE ([0-9]+)/)&&RegExp.$1<9&&(t.newStyle=function(t){var e=document.createElement("span");return e.innerHTML=' ",e})},initVars:function(){var e,n,i,a=navigator.userAgent;e="other",n=0,i=[["firefox",/Firefox\/([0-9\.]+)/],["bb",/BlackBerry.+Version\/([0-9\.]+)/],["bb",/BB[0-9]+.+Version\/([0-9\.]+)/],["opera",/OPR\/([0-9\.]+)/],["opera",/Opera\/([0-9\.]+)/],["edge",/Edge\/([0-9\.]+)/],["safari",/Version\/([0-9\.]+).+Safari/],["chrome",/Chrome\/([0-9\.]+)/],["ie",/MSIE ([0-9]+)/],["ie",/Trident\/.+rv:([0-9]+)/]],t.iterate(i,function(t,i){return a.match(i[1])?(e=i[0],n=parseFloat(RegExp.$1),!1):void 0}),t.vars.browser=e,t.vars.browserVersion=n,e="other",n=0,i=[["ios",/([0-9_]+) like Mac OS X/,function(t){return t.replace("_",".").replace("_","")}],["ios",/CPU like Mac OS X/,function(t){return 0}],["android",/Android ([0-9\.]+)/,null],["mac",/Macintosh.+Mac OS X ([0-9_]+)/,function(t){return t.replace("_",".").replace("_","")}],["wp",/Windows Phone ([0-9\.]+)/,null],["windows",/Windows NT ([0-9\.]+)/,null],["bb",/BlackBerry.+Version\/([0-9\.]+)/,null],["bb",/BB[0-9]+.+Version\/([0-9\.]+)/,null]],t.iterate(i,function(t,i){return a.match(i[1])?(e=i[0],n=parseFloat(i[2]?i[2](RegExp.$1):RegExp.$1),!1):void 0}),t.vars.os=e,t.vars.osVersion=n,t.vars.IEVersion="ie"==t.vars.browser?t.vars.browserVersion:99,t.vars.touch="wp"==t.vars.os?navigator.msMaxTouchPoints>0:!!("ontouchstart"in window),t.vars.mobile="wp"==t.vars.os||"android"==t.vars.os||"ios"==t.vars.os||"bb"==t.vars.os}};return t.init(),t}();!function(t,e){"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?module.exports=e():t.skel=e()}(this,function(){return skel}); 3 | -------------------------------------------------------------------------------- /cgpp2018.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | 3 | $('#calendar').fullCalendar({ 4 | events: [ 5 | { 6 | title : 'Collaboration and Exploration', 7 | start : '2018-01-25T16:30:00', 8 | end : '2018-01-25T18:15:00', 9 | allday : false 10 | }, 11 | { 12 | title : 'Collaboration and Exploration 2', 13 | start : '2018-02-01T16:30:00', 14 | end : '2018-02-01T18:15:00', 15 | allday : false 16 | }, 17 | { 18 | title : 'Collaboration and Exploration 3', 19 | start : '2018-02-08T16:30:00', 20 | end : '2018-02-08T18:15:00', 21 | allday : false 22 | }, 23 | { 24 | title : 'Wormhole Traversals', 25 | start : '2018-02-15T16:30:00', 26 | end : '2018-02-15T18:15:00', 27 | allday : false 28 | }, 29 | { 30 | title : 'D3 Workshop', 31 | start : '2018-02-22T16:30:00', 32 | end : '2018-02-22T18:15:00', 33 | allday : false 34 | } 35 | ] 36 | }); 37 | }); -------------------------------------------------------------------------------- /cgppSchedule.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | CGPP Schedule 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | Return Home 20 |
21 |
22 |
23 |

Meetings in Allen Library Red A/C 24 | Every other Tuesday @4:30pm 25 |

26 |
27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 7 | 8 | UW Computer Graphics & Pretty Pictures 9 | 10 | 11 | 12 | 13 | 14 | 15 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 51 | 52 | 74 | 75 | 76 |
77 |
78 | 79 |
80 | 81 |
82 | 83 | 84 | 88 | 89 |
90 |

Schedule

91 | 92 | 93 |
94 |

Tutorial Projects

95 |

96 | Below are sample projects we've made with three.js, p5.js, A-Frame, and Shadertoy. 97 |

98 | 99 | 100 |
101 |
102 |
103 |

Lighting

104 | 105 | 106 | 107 | 108 |
109 | 110 |
111 |

Simple Controls

112 | 113 | 114 | 115 | 116 |
117 | 118 |
119 |

Hierarchy Rotation

120 | 121 | 122 | 123 | 124 |
125 | 126 |
127 |

Music Visualizer

128 | 129 | 130 | 131 | 132 |
133 | 134 |
135 |

2D Simplex Noise

136 | 137 | 138 | 139 | 140 |
141 |
142 |
143 |
144 |

Multiple Objects

145 | 146 | 147 | 148 | 149 |
150 | 151 |
152 |

Shaders

153 | 154 | 155 | 156 | 157 |
158 | 159 |
160 |

Shader Fractal-Torus

161 | 162 | 163 | 164 | 165 |
166 | 167 |
168 |

A-Frame VR Portfolio Demo

169 | 170 | 171 | 172 | 173 |
174 |
175 |
176 |
177 |

Starbucks

178 | 179 | 180 | 181 | 182 | 183 |
184 | 185 |
186 | 187 |

Fire and Water

188 | 189 | 190 | 191 | 192 |
193 | 194 |
195 |

Volumetric Rendering

196 | 197 | 198 | 199 | 200 |
201 | 202 |
203 |

P5.js Noise Field

204 | 205 | 206 | 207 | 208 |
209 | 210 |
211 |
212 | 213 | 214 | 215 |
216 | 217 |
218 |

About Us

219 |
220 |
221 |

222 | We are a student organization at the University of Washington dedicated to learning, teaching, and developing computer graphics. CGPP aims to introduce students to modern graphics tools and concepts to allow them to use programing as a creative medium. These topics and tools range from music visualizers, games, VR/AR, CAD software, or animated movies. Our main focus is on real-time interactive graphics, especially on the web via WebGL with libraries like three.js. This platform is ideal because javascript is relatively easy to learn, requires virtually no setup or installation, and targets a vast array of devices - all modern smartphones, tablets, laptop and desktop computers. Our goal is to build a community that is capable of collaborating on meaningful projects. 223 |

224 |
225 | 226 |

227 | 228 | 229 | 230 | 231 |         232 | 233 | 234 | 235 |

236 |

Contact

237 |

238 | Lee Polla 239 |
240 | Peter Whidden 241 |
242 | Torin Blankensmith 243 | 244 |

245 |
246 | 247 |
248 |
249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | -------------------------------------------------------------------------------- /js/ColorTracker.js: -------------------------------------------------------------------------------- 1 | function ColorTracker(tracker1, tracker2) { 2 | this.tracker1 = tracker1 ? tracker1 : new ColorTracking(0.1, 0.8); 3 | this.tracker2 = tracker2 ? tracker2 : new ColorTracking(0.1, 0.8); 4 | } 5 | 6 | ColorTracker.prototype.update = function() { 7 | this.tracker1.update(); 8 | this.tracker2.update(); 9 | } 10 | 11 | ColorTracker.prototype.getColor = function(intensity, peak) { 12 | 13 | var red1 = this.tracker1.red; 14 | var green1 = this.tracker1.green; 15 | var blue1 = this.tracker1.blue; 16 | var red2 = 255 - this.tracker2.red; 17 | var green2 = 255 - this.tracker2.green; 18 | var blue2 = 255 - this.tracker2.blue; 19 | 20 | var shift2 = intensity / peak; 21 | var shift1 = 1 - shift2; 22 | 23 | var r = red1 * shift1 + red2 * shift2; 24 | var g = green1 * shift1 + green2 * shift2; 25 | var b = blue1 * shift1 + blue2 * shift2; 26 | var alpha = Math.min(255 * shift2, 255); 27 | return new THREE.Color(r/255, g/255, b/255, alpha/255); 28 | } 29 | 30 | function ColorTracking(deltaMin, deltaMax, redStart, greenStart, blueStart) { 31 | this.deltaMin = deltaMin; 32 | this.deltaMax = deltaMax; 33 | this.incrRed = true; 34 | this.incrBlue = false; 35 | this.incrGreen = false; 36 | this.red = redStart ? redStart: Math.random(125, 255); 37 | this.green = greenStart ? greenStart: Math.random(0, 125); 38 | this.blue = blueStart ? blueStart: Math.random(67, 200); 39 | this.dr = Math.random(this.deltaMin, this.deltaMax); 40 | this.dg = Math.random(this.deltaMin, this.deltaMax); 41 | this.db = Math.random(this.deltaMin, this.deltaMax); 42 | } 43 | 44 | ColorTracking.prototype.pickRandomDeltas = function() { 45 | this.dr = Math.random(this.deltaMin, this.deltaMax); 46 | this.dg = Math.random(this.deltaMin, this.deltaMax); 47 | this.db = Math.random(this.deltaMin, this.deltaMax); 48 | }; 49 | 50 | //call each frame to slowly change colors over time 51 | ColorTracking.prototype.update = function() { 52 | if (this.red + this.blue + this.green < 255) { 53 | this.incrRed = true; 54 | this.incrBlue = true; 55 | this.incrGreen = true; 56 | this.pickRandomDeltas(); 57 | 58 | } else if (this.red + this.blue + this.green > (255 * 2)) { 59 | this.incrRed = false; 60 | this.incrBlue = false; 61 | this.incrGreen = false; 62 | this.pickRandomDeltas(); 63 | } 64 | 65 | if (this.red > 255) { 66 | this.incrRed = false; 67 | this.dr = Math.random(this.deltaMin, this.deltaMax); 68 | } 69 | if (this.blue > 255) { 70 | this.incrBlue = false; 71 | this.db = Math.random(this.deltaMin, this.deltaMax); 72 | } 73 | if (this.green > 255) { 74 | this.incrGreen = false; 75 | this.dg = Math.random(this.deltaMin, this.deltaMax); 76 | } 77 | if (this.red < 0) this.incrRed = true; 78 | if (this.blue < 0) this.incrBlue = true; 79 | if (this.green < 0) this.incrGreen = true; 80 | 81 | if (this.incrRed) this.red += this.dr; 82 | else this.red -= this.dr; 83 | if (this.incrBlue) this.blue += this.db; 84 | else this.blue -= this.db; 85 | if (this.incrGreen) this.green += this.dg; 86 | else this.green -= this.dg; 87 | }; 88 | 89 | ColorTracking.prototype.pickRandomColor = function () { 90 | this.red = Math.random(0, 255); 91 | this.green = Math.random(0, 255); 92 | this.blue = Math.random(0, 255); 93 | }; 94 | -------------------------------------------------------------------------------- /js/CopyShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Full-screen textured quad shader 5 | */ 6 | 7 | THREE.CopyShader = { 8 | 9 | uniforms: { 10 | 11 | "tDiffuse": { value: null }, 12 | "opacity": { value: 1.0 } 13 | 14 | }, 15 | 16 | vertexShader: [ 17 | 18 | "varying vec2 vUv;", 19 | 20 | "void main() {", 21 | 22 | "vUv = uv;", 23 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 24 | 25 | "}" 26 | 27 | ].join( "\n" ), 28 | 29 | fragmentShader: [ 30 | 31 | "uniform float opacity;", 32 | 33 | "uniform sampler2D tDiffuse;", 34 | 35 | "varying vec2 vUv;", 36 | 37 | "void main() {", 38 | 39 | "vec4 texel = texture2D( tDiffuse, vUv );", 40 | "gl_FragColor = opacity * texel;", 41 | 42 | "}" 43 | 44 | ].join( "\n" ) 45 | 46 | }; 47 | -------------------------------------------------------------------------------- /js/Detector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * @author mr.doob / http://mrdoob.com/ 4 | */ 5 | 6 | var Detector = { 7 | 8 | canvas: !! window.CanvasRenderingContext2D, 9 | webgl: ( function () { 10 | 11 | try { 12 | 13 | var canvas = document.createElement( 'canvas' ); return !! ( window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ) ); 14 | 15 | } catch ( e ) { 16 | 17 | return false; 18 | 19 | } 20 | 21 | } )(), 22 | workers: !! window.Worker, 23 | fileapi: window.File && window.FileReader && window.FileList && window.Blob, 24 | 25 | getWebGLErrorMessage: function () { 26 | 27 | var element = document.createElement( 'div' ); 28 | element.id = 'webgl-error-message'; 29 | element.style.fontFamily = 'monospace'; 30 | element.style.fontSize = '13px'; 31 | element.style.fontWeight = 'normal'; 32 | element.style.textAlign = 'center'; 33 | element.style.background = '#fff'; 34 | element.style.color = '#000'; 35 | element.style.padding = '1.5em'; 36 | element.style.width = '400px'; 37 | element.style.margin = '5em auto 0'; 38 | 39 | if ( ! this.webgl ) { 40 | 41 | element.innerHTML = window.WebGLRenderingContext ? [ 42 | 'Your graphics card does not seem to support WebGL.
', 43 | 'Find out how to get it here.' 44 | ].join( '\n' ) : [ 45 | 'Your browser does not seem to support WebGL.
', 46 | 'Find out how to get it here.' 47 | ].join( '\n' ); 48 | 49 | } 50 | 51 | return element; 52 | 53 | }, 54 | 55 | addGetWebGLMessage: function ( parameters ) { 56 | 57 | var parent, id, element; 58 | 59 | parameters = parameters || {}; 60 | 61 | parent = parameters.parent !== undefined ? parameters.parent : document.body; 62 | id = parameters.id !== undefined ? parameters.id : 'oldie'; 63 | 64 | element = Detector.getWebGLErrorMessage(); 65 | element.id = id; 66 | 67 | parent.appendChild( element ); 68 | 69 | } 70 | 71 | }; 72 | 73 | // browserify support 74 | if ( typeof module === 'object' ) { 75 | 76 | module.exports = Detector; 77 | 78 | } 79 | -------------------------------------------------------------------------------- /js/EffectComposer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.EffectComposer = function ( renderer, renderTarget ) { 6 | 7 | this.renderer = renderer; 8 | 9 | if ( renderTarget === undefined ) { 10 | 11 | var parameters = { 12 | minFilter: THREE.LinearFilter, 13 | magFilter: THREE.LinearFilter, 14 | format: THREE.RGBAFormat, 15 | stencilBuffer: false 16 | }; 17 | var size = renderer.getSize(); 18 | renderTarget = new THREE.WebGLRenderTarget( size.width, size.height, parameters ); 19 | 20 | } 21 | 22 | this.renderTarget1 = renderTarget; 23 | this.renderTarget2 = renderTarget.clone(); 24 | 25 | this.writeBuffer = this.renderTarget1; 26 | this.readBuffer = this.renderTarget2; 27 | 28 | this.passes = []; 29 | 30 | if ( THREE.CopyShader === undefined ) 31 | console.error( "THREE.EffectComposer relies on THREE.CopyShader" ); 32 | 33 | this.copyPass = new THREE.ShaderPass( THREE.CopyShader ); 34 | 35 | }; 36 | 37 | Object.assign( THREE.EffectComposer.prototype, { 38 | 39 | swapBuffers: function() { 40 | 41 | var tmp = this.readBuffer; 42 | this.readBuffer = this.writeBuffer; 43 | this.writeBuffer = tmp; 44 | 45 | }, 46 | 47 | addPass: function ( pass ) { 48 | 49 | this.passes.push( pass ); 50 | 51 | var size = this.renderer.getSize(); 52 | pass.setSize( size.width, size.height ); 53 | 54 | }, 55 | 56 | insertPass: function ( pass, index ) { 57 | 58 | this.passes.splice( index, 0, pass ); 59 | 60 | }, 61 | 62 | render: function ( delta ) { 63 | 64 | var maskActive = false; 65 | 66 | var pass, i, il = this.passes.length; 67 | 68 | for ( i = 0; i < il; i ++ ) { 69 | 70 | pass = this.passes[ i ]; 71 | 72 | if ( pass.enabled === false ) continue; 73 | 74 | pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive ); 75 | 76 | if ( pass.needsSwap ) { 77 | 78 | if ( maskActive ) { 79 | 80 | var context = this.renderer.context; 81 | 82 | context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff ); 83 | 84 | this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta ); 85 | 86 | context.stencilFunc( context.EQUAL, 1, 0xffffffff ); 87 | 88 | } 89 | 90 | this.swapBuffers(); 91 | 92 | } 93 | 94 | if ( THREE.MaskPass !== undefined ) { 95 | 96 | if ( pass instanceof THREE.MaskPass ) { 97 | 98 | maskActive = true; 99 | 100 | } else if ( pass instanceof THREE.ClearMaskPass ) { 101 | 102 | maskActive = false; 103 | 104 | } 105 | 106 | } 107 | 108 | } 109 | 110 | }, 111 | 112 | reset: function ( renderTarget ) { 113 | 114 | if ( renderTarget === undefined ) { 115 | 116 | var size = this.renderer.getSize(); 117 | 118 | renderTarget = this.renderTarget1.clone(); 119 | renderTarget.setSize( size.width, size.height ); 120 | 121 | } 122 | 123 | this.renderTarget1.dispose(); 124 | this.renderTarget2.dispose(); 125 | this.renderTarget1 = renderTarget; 126 | this.renderTarget2 = renderTarget.clone(); 127 | 128 | this.writeBuffer = this.renderTarget1; 129 | this.readBuffer = this.renderTarget2; 130 | 131 | }, 132 | 133 | setSize: function ( width, height ) { 134 | 135 | this.renderTarget1.setSize( width, height ); 136 | this.renderTarget2.setSize( width, height ); 137 | 138 | for ( var i = 0; i < this.passes.length; i ++ ) { 139 | 140 | this.passes[i].setSize( width, height ); 141 | 142 | } 143 | 144 | } 145 | 146 | } ); 147 | 148 | 149 | THREE.Pass = function () { 150 | 151 | // if set to true, the pass is processed by the composer 152 | this.enabled = true; 153 | 154 | // if set to true, the pass indicates to swap read and write buffer after rendering 155 | this.needsSwap = true; 156 | 157 | // if set to true, the pass clears its buffer before rendering 158 | this.clear = false; 159 | 160 | // if set to true, the result of the pass is rendered to screen 161 | this.renderToScreen = false; 162 | 163 | }; 164 | 165 | Object.assign( THREE.Pass.prototype, { 166 | 167 | setSize: function( width, height ) {}, 168 | 169 | render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { 170 | 171 | console.error( "THREE.Pass: .render() must be implemented in derived pass." ); 172 | 173 | } 174 | 175 | } ); 176 | -------------------------------------------------------------------------------- /js/ExplodeModifier.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Make all faces use unique vertices 3 | * so that each face can be separated from others 4 | * 5 | * @author alteredq / http://alteredqualia.com/ 6 | */ 7 | 8 | THREE.ExplodeModifier = function () { 9 | 10 | }; 11 | 12 | THREE.ExplodeModifier.prototype.modify = function ( geometry ) { 13 | 14 | var vertices = []; 15 | 16 | for ( var i = 0, il = geometry.faces.length; i < il; i ++ ) { 17 | 18 | var n = vertices.length; 19 | 20 | var face = geometry.faces[ i ]; 21 | 22 | var a = face.a; 23 | var b = face.b; 24 | var c = face.c; 25 | 26 | var va = geometry.vertices[ a ]; 27 | var vb = geometry.vertices[ b ]; 28 | var vc = geometry.vertices[ c ]; 29 | 30 | vertices.push( va.clone() ); 31 | vertices.push( vb.clone() ); 32 | vertices.push( vc.clone() ); 33 | 34 | face.a = n; 35 | face.b = n + 1; 36 | face.c = n + 2; 37 | 38 | } 39 | 40 | geometry.vertices = vertices; 41 | 42 | }; 43 | -------------------------------------------------------------------------------- /js/GeometryWorker.js: -------------------------------------------------------------------------------- 1 | 2 | importScripts('three.js'); 3 | importScripts('TessellateModifier.js'); 4 | 5 | onmessage = function(e) { 6 | var geomToUpdate = e.data[0]; //'A' or 'B' 7 | var selectedGeometry = e.data[1]; 8 | var size = e.data[2]; 9 | var detail = e.data[3]; 10 | var geometry; 11 | 12 | if ( selectedGeometry == "Plane" ) { 13 | geometry = new THREE.PlaneBufferGeometry(size, size, detail, detail).toNonIndexed(); 14 | } else if( selectedGeometry == "Sphere" ) { 15 | geometry = new THREE.SphereBufferGeometry(size / 2.0, detail, detail).toNonIndexed(); 16 | } else if( selectedGeometry == "Solid Sphere" ) { 17 | var triangleSize = e.data[4]; 18 | geometry = generateSolidSphereGeometry(size, detail, triangleSize).toNonIndexed(); 19 | } else if ( selectedGeometry == "Text" ) { 20 | var font = e.data[4]; 21 | var text = e.data[5]; 22 | tempFont = new THREE.Font(); 23 | tempFont.data = font.data; 24 | font = tempFont; 25 | 26 | geometry = generateText(size, detail, font, text); 27 | } 28 | postMessage([geomToUpdate, geometry]); 29 | } 30 | 31 | function generateSolidSphereGeometry(size, detail, triangleSize) { 32 | 33 | var triangles = Math.round(detail * 100); 34 | 35 | var geometry = new THREE.BufferGeometry(); 36 | 37 | var indices = new Uint32Array( triangles * 3 ); 38 | 39 | for ( var i = 0; i < indices.length; i ++ ) { 40 | indices[ i ] = i; 41 | } 42 | 43 | var positions = new Float32Array( triangles * 3 * 3 ); 44 | var normals = new Int16Array( triangles * 3 * 3 ); 45 | var colors = new Uint8Array( triangles * 3 * 3 ); 46 | 47 | var color = new THREE.Color(); 48 | 49 | var n = Math.round(size); // triangles spread in the sphere 50 | var d = Math.round(triangleSize), d2 = d/2; // individual triangle size 51 | 52 | var pA = new THREE.Vector3(); 53 | var pB = new THREE.Vector3(); 54 | var pC = new THREE.Vector3(); 55 | 56 | var cb = new THREE.Vector3(); 57 | var ab = new THREE.Vector3(); 58 | 59 | var sphereRaduis = n / 3; 60 | 61 | for ( var i = 0; i < positions.length; i += 9 ) { 62 | var x = Math.random() * n - n / 2; 63 | var y = Math.random() * n - n / 2; 64 | var z = Math.random() * n - n / 2; 65 | while(Math.sqrt(x * x + y * y + z * z) > sphereRaduis) { 66 | x = Math.random() * n - n / 2; 67 | y = Math.random() * n - n / 2; 68 | z = Math.random() * n - n / 2; 69 | } 70 | 71 | var ax = x + Math.random() * d - d2; 72 | var ay = y + Math.random() * d - d2; 73 | var az = z + Math.random() * d - d2; 74 | 75 | var bx = x + Math.random() * d - d2; 76 | var by = y + Math.random() * d - d2; 77 | var bz = z + Math.random() * d - d2; 78 | 79 | var cx = x + Math.random() * d - d2; 80 | var cy = y + Math.random() * d - d2; 81 | var cz = z + Math.random() * d - d2; 82 | 83 | positions[ i ] = ax; 84 | positions[ i + 1 ] = ay; 85 | positions[ i + 2 ] = az; 86 | 87 | positions[ i + 3 ] = bx; 88 | positions[ i + 4 ] = by; 89 | positions[ i + 5 ] = bz; 90 | 91 | positions[ i + 6 ] = cx; 92 | positions[ i + 7 ] = cy; 93 | positions[ i + 8 ] = cz; 94 | 95 | // flat face normals 96 | 97 | pA.set( ax, ay, az ); 98 | pB.set( bx, by, bz ); 99 | pC.set( cx, cy, cz ); 100 | 101 | cb.subVectors( pC, pB ); 102 | ab.subVectors( pA, pB ); 103 | cb.cross( ab ); 104 | 105 | cb.normalize(); 106 | 107 | var nx = cb.x; 108 | var ny = cb.y; 109 | var nz = cb.z; 110 | 111 | normals[ i ] = nx * 32767; 112 | normals[ i + 1 ] = ny * 32767; 113 | normals[ i + 2 ] = nz * 32767; 114 | 115 | normals[ i + 3 ] = nx * 32767; 116 | normals[ i + 4 ] = ny * 32767; 117 | normals[ i + 5 ] = nz * 32767; 118 | 119 | normals[ i + 6 ] = nx * 32767; 120 | normals[ i + 7 ] = ny * 32767; 121 | normals[ i + 8 ] = nz * 32767; 122 | 123 | // colors 124 | 125 | var vx = ( x / sphereRaduis/2 ) + 0.7; 126 | var vy = ( y / sphereRaduis/2) + 0.7; 127 | var vz = ( z / sphereRaduis/2) + 0.7; 128 | 129 | color.setRGB( vx, vy, vz ); 130 | 131 | colors[ i ] = color.r * 255; 132 | colors[ i + 1 ] = color.g * 255; 133 | colors[ i + 2 ] = color.b * 255; 134 | 135 | colors[ i + 3 ] = color.r * 255; 136 | colors[ i + 4 ] = color.g * 255; 137 | colors[ i + 5 ] = color.b * 255; 138 | 139 | colors[ i + 6 ] = color.r * 255; 140 | colors[ i + 7 ] = color.g * 255; 141 | colors[ i + 8 ] = color.b * 255; 142 | 143 | } 144 | 145 | geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) ); 146 | geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); 147 | geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3, true ) ); 148 | geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3, true ) ); 149 | geometry.computeBoundingSphere(); 150 | 151 | return geometry; 152 | } 153 | 154 | 155 | function generateText(size, detail, font, text) { 156 | 157 | var geometry = new THREE.TextGeometry( text, { 158 | font: font, 159 | size: size, 160 | height: 5, 161 | curveSegments: detail / 5.0, 162 | bevelThickness: 20, 163 | bevelSize: 1, 164 | bevelEnabled: true 165 | }); 166 | 167 | var tessellateModifier = new THREE.TessellateModifier( 10 ); 168 | 169 | for ( var i = 0; i < 10; i ++ ) { 170 | tessellateModifier.modify( geometry ); 171 | } 172 | 173 | var t = new THREE.BufferGeometry().fromGeometry( geometry ); 174 | t.computeBoundingBox(); 175 | t.computeVertexNormals(); 176 | t.center(); 177 | 178 | return t.toNonIndexed(); 179 | } -------------------------------------------------------------------------------- /js/HeaderText.js: -------------------------------------------------------------------------------- 1 | var renderer, scene, camera; 2 | var time = 500.0; 3 | var scrollPos = 0.0; 4 | var scrollVel = 0.0; 5 | 6 | var mesh, textMeshes, uniforms, scaleForMobile; 7 | 8 | var WIDTH = window.innerWidth, 9 | HEIGHT = window.innerHeight; 10 | 11 | var loader = new THREE.FontLoader(); 12 | loader.load( 'WebAssets/fonts/SharpSansNo1Medium_Regular.json', function ( font ) { 13 | 14 | init( font ); 15 | animate(); 16 | 17 | } ); 18 | 19 | function init( font ) { 20 | 21 | camera = new THREE.PerspectiveCamera( 10, WIDTH / HEIGHT, 1, 10000 ); 22 | camera.position.set( -0, 0, 1600 ); 23 | 24 | // controls = new THREE.TrackballControls( camera ); 25 | 26 | scene = new THREE.Scene(); 27 | 28 | // 29 | 30 | var positions; 31 | if (window.innerWidth > window.innerHeight) { 32 | positions = [ -120, 18, -120, -18, 5, 120, 18, 120, -18]; 33 | scaleForMobile = 1.0; 34 | } else { 35 | positions = [ 0, 85, 0, 50, 0, 0, -50, 0, -85]; 36 | scaleForMobile = 3.0; 37 | } 38 | 39 | 40 | textMeshes = new THREE.Object3D(); 41 | 42 | mesh = createText( "Computer", font ); 43 | mesh.position.x = positions[0]; 44 | mesh.position.y = positions[1]; 45 | textMeshes.add( mesh ); 46 | 47 | mesh = createText( "Graphics", font ); 48 | mesh.position.x = positions[2]; 49 | mesh.position.y = positions[3]; 50 | textMeshes.add( mesh ); 51 | 52 | mesh = createText( "&", font ); 53 | mesh.position.x = positions[4]; 54 | textMeshes.add( mesh ); 55 | 56 | mesh = createText( "Pretty", font ); 57 | mesh.position.x = positions[5]; 58 | mesh.position.y = positions[6]; 59 | textMeshes.add( mesh ); 60 | 61 | mesh = createText( "Pictures", font ); 62 | mesh.position.x = positions[7]; 63 | mesh.position.y = positions[8]; 64 | textMeshes.add( mesh ); 65 | 66 | textMeshes.scale.x = scaleForMobile*window.innerWidth/1500.0; 67 | textMeshes.scale.y = scaleForMobile*window.innerWidth/1500.0; 68 | textMeshes.scale.z = scaleForMobile*window.innerWidth/1500.0; 69 | 70 | scene.add( textMeshes ); 71 | 72 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 73 | renderer.setClearColor( 0x000000 ); 74 | renderer.setPixelRatio( window.devicePixelRatio ); 75 | renderer.setSize( WIDTH, HEIGHT ); 76 | 77 | var container = document.getElementById( 'container' ); 78 | container.appendChild( renderer.domElement ); 79 | 80 | 81 | // 82 | 83 | window.addEventListener( 'resize', onWindowResize, false ); 84 | 85 | } 86 | 87 | function createText( text, font ) { 88 | 89 | var geometry = new THREE.TextGeometry( text, { 90 | 91 | font: font, 92 | 93 | size: 28, 94 | height: 5, 95 | curveSegments: 7, 96 | 97 | bevelThickness: 2, 98 | bevelSize: 1, 99 | bevelEnabled: true 100 | 101 | }); 102 | 103 | geometry.center(); 104 | 105 | var tessellateModifier = new THREE.TessellateModifier( 12 ); 106 | 107 | for ( var i = 0; i < 15; i ++ ) { 108 | 109 | tessellateModifier.modify( geometry ); 110 | 111 | } 112 | 113 | var explodeModifier = new THREE.ExplodeModifier(); 114 | explodeModifier.modify( geometry ); 115 | 116 | var numFaces = geometry.faces.length; 117 | 118 | // 119 | 120 | geometry = new THREE.BufferGeometry().fromGeometry( geometry ); 121 | 122 | var colors = new Float32Array( numFaces * 3 * 3 ); 123 | var displacement = new Float32Array( numFaces * 3 * 3 ); 124 | 125 | var color = new THREE.Color(); 126 | 127 | for ( var f = 0; f < numFaces; f ++ ) { 128 | 129 | var index = 9 * f; 130 | 131 | var h = 0.6 + 0.2* Math.random(); 132 | var s = 0.4 + 0.3 * Math.random(); 133 | var l = 0.7 + 0.2 * Math.random(); 134 | 135 | color.setHSL( h, s, l ); 136 | 137 | var d = 10 * ( 0.5 - Math.random() ); 138 | 139 | for ( var i = 0; i < 3; i ++ ) { 140 | 141 | colors[ index + ( 3 * i ) ] = color.r; 142 | colors[ index + ( 3 * i ) + 1 ] = color.g; 143 | colors[ index + ( 3 * i ) + 2 ] = color.b; 144 | 145 | displacement[ index + ( 3 * i ) ] = d; 146 | displacement[ index + ( 3 * i ) + 1 ] = d; 147 | displacement[ index + ( 3 * i ) + 2 ] = d; 148 | 149 | } 150 | 151 | } 152 | 153 | geometry.addAttribute( 'customColor', new THREE.BufferAttribute( colors, 3 ) ); 154 | geometry.addAttribute( 'displacement', new THREE.BufferAttribute( displacement, 3 ) ); 155 | 156 | // 157 | 158 | uniforms = { 159 | 160 | amplitude: { value: 0.0 }, 161 | gTime: { value: 0.0 } 162 | 163 | }; 164 | 165 | var shaderMaterial = new THREE.ShaderMaterial( { 166 | 167 | uniforms: uniforms, 168 | vertexShader: document.getElementById( 'vertexshader' ).textContent, 169 | fragmentShader: document.getElementById( 'fragmentshader' ).textContent, 170 | transparent: true, 171 | opacity: 0.2 172 | 173 | }); 174 | 175 | // 176 | 177 | mesh = new THREE.Mesh( geometry, shaderMaterial ); 178 | mesh.frustumCulled = false; 179 | 180 | return mesh; 181 | } 182 | 183 | function onWindowResize() { 184 | 185 | camera.aspect = window.innerWidth / (window.innerHeight); 186 | camera.updateProjectionMatrix(); 187 | textMeshes.scale.x = scaleForMobile*window.innerWidth/1500.0; 188 | textMeshes.scale.y = scaleForMobile*window.innerWidth/1500.0; 189 | textMeshes.scale.z = scaleForMobile*window.innerWidth/1500.0; 190 | 191 | renderer.setSize( window.innerWidth, window.innerHeight ); 192 | 193 | } 194 | 195 | function animate() { 196 | 197 | requestAnimationFrame( animate ); 198 | 199 | render(); 200 | 201 | } 202 | 203 | function render() { 204 | 205 | time += 0.008; 206 | 207 | var scrollExact = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; 208 | //var scrollDif = scrollPos - scrollExact; 209 | //scrollVel += 0.3 * scrollDif; 210 | //scrollVel *= 0.7; 211 | //if (window.innerWidth < window.innerHeight) { 212 | scrollPos = scrollExact; 213 | //} else { 214 | // scrollPos -= 0.3 * scrollVel; 215 | //} 216 | 217 | textMeshes.rotation.x = 0.00035*scrollPos; 218 | textMeshes.position.y = 0.05*scrollPos; 219 | textMeshes.traverse( function(current) { 220 | if (current.type === 'Mesh') { 221 | 222 | current.material.uniforms.amplitude.value = 0.08*scrollPos; //1.0 + Math.sin( time * 0.5 ); 223 | current.material.uniforms.gTime.value = time; 224 | } 225 | 226 | } ); 227 | 228 | 229 | // controls.update(); 230 | 231 | renderer.render( scene, camera ); 232 | 233 | } 234 | -------------------------------------------------------------------------------- /js/LuminosityHighPassShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author bhouston / http://clara.io/ 3 | * 4 | * Luminosity 5 | * http://en.wikipedia.org/wiki/Luminosity 6 | */ 7 | 8 | THREE.LuminosityHighPassShader = { 9 | 10 | shaderID: "luminosityHighPass", 11 | 12 | uniforms: { 13 | 14 | "tDiffuse": { type: "t", value: null }, 15 | "luminosityThreshold": { type: "f", value: 1.0 }, 16 | "smoothWidth": { type: "f", value: 1.0 }, 17 | "defaultColor": { type: "c", value: new THREE.Color( 0x000000 ) }, 18 | "defaultOpacity": { type: "f", value: 0.0 }, 19 | 20 | }, 21 | 22 | vertexShader: [ 23 | 24 | "varying vec2 vUv;", 25 | 26 | "void main() {", 27 | 28 | "vUv = uv;", 29 | 30 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 31 | 32 | "}" 33 | 34 | ].join("\n"), 35 | 36 | fragmentShader: [ 37 | 38 | "uniform sampler2D tDiffuse;", 39 | "uniform vec3 defaultColor;", 40 | "uniform float defaultOpacity;", 41 | "uniform float luminosityThreshold;", 42 | "uniform float smoothWidth;", 43 | 44 | "varying vec2 vUv;", 45 | 46 | "void main() {", 47 | 48 | "vec4 texel = texture2D( tDiffuse, vUv );", 49 | 50 | "vec3 luma = vec3( 0.299, 0.587, 0.114 );", 51 | 52 | "float v = dot( texel.xyz, luma );", 53 | 54 | "vec4 outputColor = vec4( defaultColor.rgb, defaultOpacity );", 55 | 56 | "float alpha = smoothstep( luminosityThreshold, luminosityThreshold + smoothWidth, v );", 57 | 58 | "gl_FragColor = mix( outputColor, texel, alpha );", 59 | 60 | "}" 61 | 62 | ].join("\n") 63 | 64 | }; 65 | -------------------------------------------------------------------------------- /js/Mirror.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Slayvin / http://slayvin.net 3 | */ 4 | 5 | THREE.ShaderLib[ 'mirror' ] = { 6 | 7 | uniforms: { 8 | "mirrorColor": { value: new THREE.Color( 0x7F7F7F ) }, 9 | "mirrorSampler": { value: null }, 10 | "textureMatrix" : { value: new THREE.Matrix4() } 11 | }, 12 | 13 | vertexShader: [ 14 | 15 | "uniform mat4 textureMatrix;", 16 | 17 | "varying vec4 mirrorCoord;", 18 | 19 | "void main() {", 20 | 21 | "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", 22 | "vec4 worldPosition = modelMatrix * vec4( position, 1.0 );", 23 | "mirrorCoord = textureMatrix * worldPosition;", 24 | 25 | "gl_Position = projectionMatrix * mvPosition;", 26 | 27 | "}" 28 | 29 | ].join( "\n" ), 30 | 31 | fragmentShader: [ 32 | 33 | "uniform vec3 mirrorColor;", 34 | "uniform sampler2D mirrorSampler;", 35 | 36 | "varying vec4 mirrorCoord;", 37 | 38 | "float blendOverlay(float base, float blend) {", 39 | "return( base < 0.5 ? ( 2.0 * base * blend ) : (1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );", 40 | "}", 41 | 42 | "void main() {", 43 | 44 | "vec4 color = texture2DProj(mirrorSampler, mirrorCoord);", 45 | "color = vec4(blendOverlay(mirrorColor.r, color.r), blendOverlay(mirrorColor.g, color.g), blendOverlay(mirrorColor.b, color.b), 1.0);", 46 | 47 | "gl_FragColor = color;", 48 | 49 | "}" 50 | 51 | ].join( "\n" ) 52 | 53 | }; 54 | 55 | THREE.Mirror = function ( renderer, camera, options ) { 56 | 57 | THREE.Object3D.call( this ); 58 | 59 | this.name = 'mirror_' + this.id; 60 | 61 | options = options || {}; 62 | 63 | this.matrixNeedsUpdate = true; 64 | 65 | var width = options.textureWidth !== undefined ? options.textureWidth : 512; 66 | var height = options.textureHeight !== undefined ? options.textureHeight : 512; 67 | 68 | this.clipBias = options.clipBias !== undefined ? options.clipBias : 0.0; 69 | 70 | var mirrorColor = options.color !== undefined ? new THREE.Color( options.color ) : new THREE.Color( 0x7F7F7F ); 71 | 72 | this.renderer = renderer; 73 | this.mirrorPlane = new THREE.Plane(); 74 | this.normal = new THREE.Vector3( 0, 0, 1 ); 75 | this.mirrorWorldPosition = new THREE.Vector3(); 76 | this.cameraWorldPosition = new THREE.Vector3(); 77 | this.rotationMatrix = new THREE.Matrix4(); 78 | this.lookAtPosition = new THREE.Vector3( 0, 0, - 1 ); 79 | this.clipPlane = new THREE.Vector4(); 80 | 81 | // For debug only, show the normal and plane of the mirror 82 | var debugMode = options.debugMode !== undefined ? options.debugMode : false; 83 | 84 | if ( debugMode ) { 85 | 86 | var arrow = new THREE.ArrowHelper( new THREE.Vector3( 0, 0, 1 ), new THREE.Vector3( 0, 0, 0 ), 10, 0xffff80 ); 87 | var planeGeometry = new THREE.Geometry(); 88 | planeGeometry.vertices.push( new THREE.Vector3( - 10, - 10, 0 ) ); 89 | planeGeometry.vertices.push( new THREE.Vector3( 10, - 10, 0 ) ); 90 | planeGeometry.vertices.push( new THREE.Vector3( 10, 10, 0 ) ); 91 | planeGeometry.vertices.push( new THREE.Vector3( - 10, 10, 0 ) ); 92 | planeGeometry.vertices.push( planeGeometry.vertices[ 0 ] ); 93 | var plane = new THREE.Line( planeGeometry, new THREE.LineBasicMaterial( { color: 0xffff80 } ) ); 94 | 95 | this.add( arrow ); 96 | this.add( plane ); 97 | 98 | } 99 | 100 | if ( camera instanceof THREE.PerspectiveCamera ) { 101 | 102 | this.camera = camera; 103 | 104 | } else { 105 | 106 | this.camera = new THREE.PerspectiveCamera(); 107 | console.log( this.name + ': camera is not a Perspective Camera!' ); 108 | 109 | } 110 | 111 | this.textureMatrix = new THREE.Matrix4(); 112 | 113 | this.mirrorCamera = this.camera.clone(); 114 | this.mirrorCamera.matrixAutoUpdate = true; 115 | 116 | var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false }; 117 | 118 | this.renderTarget = new THREE.WebGLRenderTarget( width, height, parameters ); 119 | this.renderTarget2 = new THREE.WebGLRenderTarget( width, height, parameters ); 120 | 121 | var mirrorShader = THREE.ShaderLib[ "mirror" ]; 122 | var mirrorUniforms = THREE.UniformsUtils.clone( mirrorShader.uniforms ); 123 | 124 | this.material = new THREE.ShaderMaterial( { 125 | 126 | fragmentShader: mirrorShader.fragmentShader, 127 | vertexShader: mirrorShader.vertexShader, 128 | uniforms: mirrorUniforms 129 | 130 | } ); 131 | 132 | this.material.uniforms.mirrorSampler.value = this.renderTarget.texture; 133 | this.material.uniforms.mirrorColor.value = mirrorColor; 134 | this.material.uniforms.textureMatrix.value = this.textureMatrix; 135 | 136 | if ( ! THREE.Math.isPowerOfTwo( width ) || ! THREE.Math.isPowerOfTwo( height ) ) { 137 | 138 | this.renderTarget.texture.generateMipmaps = false; 139 | this.renderTarget2.texture.generateMipmaps = false; 140 | 141 | } 142 | 143 | this.updateTextureMatrix(); 144 | this.render(); 145 | 146 | }; 147 | 148 | THREE.Mirror.prototype = Object.create( THREE.Object3D.prototype ); 149 | THREE.Mirror.prototype.constructor = THREE.Mirror; 150 | 151 | THREE.Mirror.prototype.renderWithMirror = function ( otherMirror ) { 152 | 153 | // update the mirror matrix to mirror the current view 154 | this.updateTextureMatrix(); 155 | this.matrixNeedsUpdate = false; 156 | 157 | // set the camera of the other mirror so the mirrored view is the reference view 158 | var tempCamera = otherMirror.camera; 159 | otherMirror.camera = this.mirrorCamera; 160 | 161 | // render the other mirror in temp texture 162 | otherMirror.renderTemp(); 163 | otherMirror.material.uniforms.mirrorSampler.value = otherMirror.renderTarget2.texture; 164 | 165 | // render the current mirror 166 | this.render(); 167 | this.matrixNeedsUpdate = true; 168 | 169 | // restore material and camera of other mirror 170 | otherMirror.material.uniforms.mirrorSampler.value = otherMirror.renderTarget.texture; 171 | otherMirror.camera = tempCamera; 172 | 173 | // restore texture matrix of other mirror 174 | otherMirror.updateTextureMatrix(); 175 | 176 | }; 177 | 178 | THREE.Mirror.prototype.updateTextureMatrix = function () { 179 | 180 | this.updateMatrixWorld(); 181 | this.camera.updateMatrixWorld(); 182 | 183 | this.mirrorWorldPosition.setFromMatrixPosition( this.matrixWorld ); 184 | this.cameraWorldPosition.setFromMatrixPosition( this.camera.matrixWorld ); 185 | 186 | this.rotationMatrix.extractRotation( this.matrixWorld ); 187 | 188 | this.normal.set( 0, 0, 1 ); 189 | this.normal.applyMatrix4( this.rotationMatrix ); 190 | 191 | var view = this.mirrorWorldPosition.clone().sub( this.cameraWorldPosition ); 192 | view.reflect( this.normal ).negate(); 193 | view.add( this.mirrorWorldPosition ); 194 | 195 | this.rotationMatrix.extractRotation( this.camera.matrixWorld ); 196 | 197 | this.lookAtPosition.set( 0, 0, - 1 ); 198 | this.lookAtPosition.applyMatrix4( this.rotationMatrix ); 199 | this.lookAtPosition.add( this.cameraWorldPosition ); 200 | 201 | var target = this.mirrorWorldPosition.clone().sub( this.lookAtPosition ); 202 | target.reflect( this.normal ).negate(); 203 | target.add( this.mirrorWorldPosition ); 204 | 205 | this.up.set( 0, - 1, 0 ); 206 | this.up.applyMatrix4( this.rotationMatrix ); 207 | this.up.reflect( this.normal ).negate(); 208 | 209 | this.mirrorCamera.position.copy( view ); 210 | this.mirrorCamera.up = this.up; 211 | this.mirrorCamera.lookAt( target ); 212 | 213 | this.mirrorCamera.updateProjectionMatrix(); 214 | this.mirrorCamera.updateMatrixWorld(); 215 | this.mirrorCamera.matrixWorldInverse.getInverse( this.mirrorCamera.matrixWorld ); 216 | 217 | // Update the texture matrix 218 | this.textureMatrix.set( 0.5, 0.0, 0.0, 0.5, 219 | 0.0, 0.5, 0.0, 0.5, 220 | 0.0, 0.0, 0.5, 0.5, 221 | 0.0, 0.0, 0.0, 1.0 ); 222 | this.textureMatrix.multiply( this.mirrorCamera.projectionMatrix ); 223 | this.textureMatrix.multiply( this.mirrorCamera.matrixWorldInverse ); 224 | 225 | // Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html 226 | // Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf 227 | this.mirrorPlane.setFromNormalAndCoplanarPoint( this.normal, this.mirrorWorldPosition ); 228 | this.mirrorPlane.applyMatrix4( this.mirrorCamera.matrixWorldInverse ); 229 | 230 | this.clipPlane.set( this.mirrorPlane.normal.x, this.mirrorPlane.normal.y, this.mirrorPlane.normal.z, this.mirrorPlane.constant ); 231 | 232 | var q = new THREE.Vector4(); 233 | var projectionMatrix = this.mirrorCamera.projectionMatrix; 234 | 235 | q.x = ( Math.sign( this.clipPlane.x ) + projectionMatrix.elements[ 8 ] ) / projectionMatrix.elements[ 0 ]; 236 | q.y = ( Math.sign( this.clipPlane.y ) + projectionMatrix.elements[ 9 ] ) / projectionMatrix.elements[ 5 ]; 237 | q.z = - 1.0; 238 | q.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ]; 239 | 240 | // Calculate the scaled plane vector 241 | var c = new THREE.Vector4(); 242 | c = this.clipPlane.multiplyScalar( 2.0 / this.clipPlane.dot( q ) ); 243 | 244 | // Replacing the third row of the projection matrix 245 | projectionMatrix.elements[ 2 ] = c.x; 246 | projectionMatrix.elements[ 6 ] = c.y; 247 | projectionMatrix.elements[ 10 ] = c.z + 1.0 - this.clipBias; 248 | projectionMatrix.elements[ 14 ] = c.w; 249 | 250 | }; 251 | 252 | THREE.Mirror.prototype.render = function () { 253 | 254 | if ( this.matrixNeedsUpdate ) this.updateTextureMatrix(); 255 | 256 | this.matrixNeedsUpdate = true; 257 | 258 | // Render the mirrored view of the current scene into the target texture 259 | var scene = this; 260 | 261 | while ( scene.parent !== null ) { 262 | 263 | scene = scene.parent; 264 | 265 | } 266 | 267 | if ( scene !== undefined && scene instanceof THREE.Scene ) { 268 | 269 | // We can't render ourself to ourself 270 | var visible = this.material.visible; 271 | this.material.visible = false; 272 | 273 | this.renderer.render( scene, this.mirrorCamera, this.renderTarget, true ); 274 | 275 | this.material.visible = visible; 276 | 277 | } 278 | 279 | }; 280 | 281 | THREE.Mirror.prototype.renderTemp = function () { 282 | 283 | if ( this.matrixNeedsUpdate ) this.updateTextureMatrix(); 284 | 285 | this.matrixNeedsUpdate = true; 286 | 287 | // Render the mirrored view of the current scene into the target texture 288 | var scene = this; 289 | 290 | while ( scene.parent !== null ) { 291 | 292 | scene = scene.parent; 293 | 294 | } 295 | 296 | if ( scene !== undefined && scene instanceof THREE.Scene ) { 297 | 298 | this.renderer.render( scene, this.mirrorCamera, this.renderTarget2, true ); 299 | 300 | } 301 | 302 | }; 303 | -------------------------------------------------------------------------------- /js/MobileAndTabletCheck.js: -------------------------------------------------------------------------------- 1 | window.mobileAndTabletCheck = function() { 2 | var check = false; 3 | (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera); 4 | return check; 5 | }; -------------------------------------------------------------------------------- /js/RenderPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.RenderPass = function ( scene, camera, overrideMaterial, clearColor, clearAlpha ) { 6 | 7 | THREE.Pass.call( this ); 8 | 9 | this.scene = scene; 10 | this.camera = camera; 11 | 12 | this.overrideMaterial = overrideMaterial; 13 | 14 | this.clearColor = clearColor; 15 | this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 0; 16 | 17 | this.clear = true; 18 | this.needsSwap = false; 19 | 20 | }; 21 | 22 | THREE.RenderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), { 23 | 24 | constructor: THREE.RenderPass, 25 | 26 | render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { 27 | 28 | var oldAutoClear = renderer.autoClear; 29 | renderer.autoClear = false; 30 | 31 | this.scene.overrideMaterial = this.overrideMaterial; 32 | 33 | var oldClearColor, oldClearAlpha; 34 | 35 | if ( this.clearColor ) { 36 | 37 | oldClearColor = renderer.getClearColor().getHex(); 38 | oldClearAlpha = renderer.getClearAlpha(); 39 | 40 | renderer.setClearColor( this.clearColor, this.clearAlpha ); 41 | 42 | } 43 | 44 | renderer.render( this.scene, this.camera, this.renderToScreen ? null : readBuffer, this.clear ); 45 | 46 | if ( this.clearColor ) { 47 | 48 | renderer.setClearColor( oldClearColor, oldClearAlpha ); 49 | 50 | } 51 | 52 | this.scene.overrideMaterial = null; 53 | renderer.autoClear = oldAutoClear; 54 | } 55 | 56 | } ); 57 | -------------------------------------------------------------------------------- /js/ShaderPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.ShaderPass = function ( shader, textureID ) { 6 | 7 | THREE.Pass.call( this ); 8 | 9 | this.textureID = ( textureID !== undefined ) ? textureID : "tDiffuse"; 10 | 11 | if ( shader instanceof THREE.ShaderMaterial ) { 12 | 13 | this.uniforms = shader.uniforms; 14 | 15 | this.material = shader; 16 | 17 | } else if ( shader ) { 18 | 19 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 20 | 21 | this.material = new THREE.ShaderMaterial( { 22 | 23 | defines: shader.defines || {}, 24 | uniforms: this.uniforms, 25 | vertexShader: shader.vertexShader, 26 | fragmentShader: shader.fragmentShader 27 | 28 | } ); 29 | 30 | } 31 | 32 | this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); 33 | this.scene = new THREE.Scene(); 34 | 35 | this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null ); 36 | this.scene.add( this.quad ); 37 | 38 | }; 39 | 40 | THREE.ShaderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), { 41 | 42 | constructor: THREE.ShaderPass, 43 | 44 | render: function( renderer, writeBuffer, readBuffer, delta, maskActive ) { 45 | 46 | if ( this.uniforms[ this.textureID ] ) { 47 | 48 | this.uniforms[ this.textureID ].value = readBuffer.texture; 49 | 50 | } 51 | 52 | this.quad.material = this.material; 53 | 54 | if ( this.renderToScreen ) { 55 | 56 | renderer.render( this.scene, this.camera ); 57 | 58 | } else { 59 | 60 | renderer.render( this.scene, this.camera, writeBuffer, this.clear ); 61 | 62 | } 63 | 64 | } 65 | 66 | } ); 67 | -------------------------------------------------------------------------------- /js/SubdivisionModifier.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog 3 | * @author centerionware / http://www.centerionware.com 4 | * 5 | * Subdivision Geometry Modifier 6 | * using Loop Subdivision Scheme 7 | * 8 | * References: 9 | * http://graphics.stanford.edu/~mdfisher/subdivision.html 10 | * http://www.holmes3d.net/graphics/subdivision/ 11 | * http://www.cs.rutgers.edu/~decarlo/readings/subdiv-sg00c.pdf 12 | * 13 | * Known Issues: 14 | * - currently doesn't handle "Sharp Edges" 15 | */ 16 | 17 | THREE.SubdivisionModifier = function ( subdivisions ) { 18 | 19 | this.subdivisions = ( subdivisions === undefined ) ? 1 : subdivisions; 20 | 21 | }; 22 | 23 | // Applies the "modify" pattern 24 | THREE.SubdivisionModifier.prototype.modify = function ( geometry ) { 25 | 26 | var repeats = this.subdivisions; 27 | 28 | while ( repeats -- > 0 ) { 29 | 30 | this.smooth( geometry ); 31 | 32 | } 33 | 34 | geometry.computeFaceNormals(); 35 | geometry.computeVertexNormals(); 36 | 37 | }; 38 | 39 | ( function() { 40 | 41 | // Some constants 42 | var WARNINGS = ! true; // Set to true for development 43 | var ABC = [ 'a', 'b', 'c' ]; 44 | 45 | 46 | function getEdge( a, b, map ) { 47 | 48 | var vertexIndexA = Math.min( a, b ); 49 | var vertexIndexB = Math.max( a, b ); 50 | 51 | var key = vertexIndexA + "_" + vertexIndexB; 52 | 53 | return map[ key ]; 54 | 55 | } 56 | 57 | 58 | function processEdge( a, b, vertices, map, face, metaVertices ) { 59 | 60 | var vertexIndexA = Math.min( a, b ); 61 | var vertexIndexB = Math.max( a, b ); 62 | 63 | var key = vertexIndexA + "_" + vertexIndexB; 64 | 65 | var edge; 66 | 67 | if ( key in map ) { 68 | 69 | edge = map[ key ]; 70 | 71 | } else { 72 | 73 | var vertexA = vertices[ vertexIndexA ]; 74 | var vertexB = vertices[ vertexIndexB ]; 75 | 76 | edge = { 77 | 78 | a: vertexA, // pointer reference 79 | b: vertexB, 80 | newEdge: null, 81 | // aIndex: a, // numbered reference 82 | // bIndex: b, 83 | faces: [] // pointers to face 84 | 85 | }; 86 | 87 | map[ key ] = edge; 88 | 89 | } 90 | 91 | edge.faces.push( face ); 92 | 93 | metaVertices[ a ].edges.push( edge ); 94 | metaVertices[ b ].edges.push( edge ); 95 | 96 | 97 | } 98 | 99 | function generateLookups( vertices, faces, metaVertices, edges ) { 100 | 101 | var i, il, face, edge; 102 | 103 | for ( i = 0, il = vertices.length; i < il; i ++ ) { 104 | 105 | metaVertices[ i ] = { edges: [] }; 106 | 107 | } 108 | 109 | for ( i = 0, il = faces.length; i < il; i ++ ) { 110 | 111 | face = faces[ i ]; 112 | 113 | processEdge( face.a, face.b, vertices, edges, face, metaVertices ); 114 | processEdge( face.b, face.c, vertices, edges, face, metaVertices ); 115 | processEdge( face.c, face.a, vertices, edges, face, metaVertices ); 116 | 117 | } 118 | 119 | } 120 | 121 | function newFace( newFaces, a, b, c ) { 122 | 123 | newFaces.push( new THREE.Face3( a, b, c ) ); 124 | 125 | } 126 | 127 | function midpoint( a, b ) { 128 | 129 | return ( Math.abs( b - a ) / 2 ) + Math.min( a, b ); 130 | 131 | } 132 | 133 | function newUv( newUvs, a, b, c ) { 134 | 135 | newUvs.push( [ a.clone(), b.clone(), c.clone() ] ); 136 | 137 | } 138 | 139 | ///////////////////////////// 140 | 141 | // Performs one iteration of Subdivision 142 | THREE.SubdivisionModifier.prototype.smooth = function ( geometry ) { 143 | 144 | var tmp = new THREE.Vector3(); 145 | 146 | var oldVertices, oldFaces, oldUvs; 147 | var newVertices, newFaces, newUVs = []; 148 | 149 | var n, l, i, il, j, k; 150 | var metaVertices, sourceEdges; 151 | 152 | // new stuff. 153 | var sourceEdges, newEdgeVertices, newSourceVertices; 154 | 155 | oldVertices = geometry.vertices; // { x, y, z} 156 | oldFaces = geometry.faces; // { a: oldVertex1, b: oldVertex2, c: oldVertex3 } 157 | oldUvs = geometry.faceVertexUvs[ 0 ]; 158 | 159 | var hasUvs = oldUvs !== undefined && oldUvs.length > 0; 160 | 161 | /****************************************************** 162 | * 163 | * Step 0: Preprocess Geometry to Generate edges Lookup 164 | * 165 | *******************************************************/ 166 | 167 | metaVertices = new Array( oldVertices.length ); 168 | sourceEdges = {}; // Edge => { oldVertex1, oldVertex2, faces[] } 169 | 170 | generateLookups( oldVertices, oldFaces, metaVertices, sourceEdges ); 171 | 172 | 173 | /****************************************************** 174 | * 175 | * Step 1. 176 | * For each edge, create a new Edge Vertex, 177 | * then position it. 178 | * 179 | *******************************************************/ 180 | 181 | newEdgeVertices = []; 182 | var other, currentEdge, newEdge, face; 183 | var edgeVertexWeight, adjacentVertexWeight, connectedFaces; 184 | 185 | for ( i in sourceEdges ) { 186 | 187 | currentEdge = sourceEdges[ i ]; 188 | newEdge = new THREE.Vector3(); 189 | 190 | edgeVertexWeight = 3 / 8; 191 | adjacentVertexWeight = 1 / 8; 192 | 193 | connectedFaces = currentEdge.faces.length; 194 | 195 | // check how many linked faces. 2 should be correct. 196 | if ( connectedFaces != 2 ) { 197 | 198 | // if length is not 2, handle condition 199 | edgeVertexWeight = 0.5; 200 | adjacentVertexWeight = 0; 201 | 202 | if ( connectedFaces != 1 ) { 203 | 204 | if ( WARNINGS ) console.warn( 'Subdivision Modifier: Number of connected faces != 2, is: ', connectedFaces, currentEdge ); 205 | 206 | } 207 | 208 | } 209 | 210 | newEdge.addVectors( currentEdge.a, currentEdge.b ).multiplyScalar( edgeVertexWeight ); 211 | 212 | tmp.set( 0, 0, 0 ); 213 | 214 | for ( j = 0; j < connectedFaces; j ++ ) { 215 | 216 | face = currentEdge.faces[ j ]; 217 | 218 | for ( k = 0; k < 3; k ++ ) { 219 | 220 | other = oldVertices[ face[ ABC[ k ] ] ]; 221 | if ( other !== currentEdge.a && other !== currentEdge.b ) break; 222 | 223 | } 224 | 225 | tmp.add( other ); 226 | 227 | } 228 | 229 | tmp.multiplyScalar( adjacentVertexWeight ); 230 | newEdge.add( tmp ); 231 | 232 | currentEdge.newEdge = newEdgeVertices.length; 233 | newEdgeVertices.push( newEdge ); 234 | 235 | // console.log(currentEdge, newEdge); 236 | 237 | } 238 | 239 | /****************************************************** 240 | * 241 | * Step 2. 242 | * Reposition each source vertices. 243 | * 244 | *******************************************************/ 245 | 246 | var beta, sourceVertexWeight, connectingVertexWeight; 247 | var connectingEdge, connectingEdges, oldVertex, newSourceVertex; 248 | newSourceVertices = []; 249 | 250 | for ( i = 0, il = oldVertices.length; i < il; i ++ ) { 251 | 252 | oldVertex = oldVertices[ i ]; 253 | 254 | // find all connecting edges (using lookupTable) 255 | connectingEdges = metaVertices[ i ].edges; 256 | n = connectingEdges.length; 257 | 258 | if ( n == 3 ) { 259 | 260 | beta = 3 / 16; 261 | 262 | } else if ( n > 3 ) { 263 | 264 | beta = 3 / ( 8 * n ); // Warren's modified formula 265 | 266 | } 267 | 268 | // Loop's original beta formula 269 | // beta = 1 / n * ( 5/8 - Math.pow( 3/8 + 1/4 * Math.cos( 2 * Math. PI / n ), 2) ); 270 | 271 | sourceVertexWeight = 1 - n * beta; 272 | connectingVertexWeight = beta; 273 | 274 | if ( n <= 2 ) { 275 | 276 | // crease and boundary rules 277 | // console.warn('crease and boundary rules'); 278 | 279 | if ( n == 2 ) { 280 | 281 | if ( WARNINGS ) console.warn( '2 connecting edges', connectingEdges ); 282 | sourceVertexWeight = 3 / 4; 283 | connectingVertexWeight = 1 / 8; 284 | 285 | // sourceVertexWeight = 1; 286 | // connectingVertexWeight = 0; 287 | 288 | } else if ( n == 1 ) { 289 | 290 | if ( WARNINGS ) console.warn( 'only 1 connecting edge' ); 291 | 292 | } else if ( n == 0 ) { 293 | 294 | if ( WARNINGS ) console.warn( '0 connecting edges' ); 295 | 296 | } 297 | 298 | } 299 | 300 | newSourceVertex = oldVertex.clone().multiplyScalar( sourceVertexWeight ); 301 | 302 | tmp.set( 0, 0, 0 ); 303 | 304 | for ( j = 0; j < n; j ++ ) { 305 | 306 | connectingEdge = connectingEdges[ j ]; 307 | other = connectingEdge.a !== oldVertex ? connectingEdge.a : connectingEdge.b; 308 | tmp.add( other ); 309 | 310 | } 311 | 312 | tmp.multiplyScalar( connectingVertexWeight ); 313 | newSourceVertex.add( tmp ); 314 | 315 | newSourceVertices.push( newSourceVertex ); 316 | 317 | } 318 | 319 | 320 | /****************************************************** 321 | * 322 | * Step 3. 323 | * Generate Faces between source vertices 324 | * and edge vertices. 325 | * 326 | *******************************************************/ 327 | 328 | newVertices = newSourceVertices.concat( newEdgeVertices ); 329 | var sl = newSourceVertices.length, edge1, edge2, edge3; 330 | newFaces = []; 331 | 332 | var uv, x0, x1, x2; 333 | var x3 = new THREE.Vector2(); 334 | var x4 = new THREE.Vector2(); 335 | var x5 = new THREE.Vector2(); 336 | 337 | for ( i = 0, il = oldFaces.length; i < il; i ++ ) { 338 | 339 | face = oldFaces[ i ]; 340 | 341 | // find the 3 new edges vertex of each old face 342 | 343 | edge1 = getEdge( face.a, face.b, sourceEdges ).newEdge + sl; 344 | edge2 = getEdge( face.b, face.c, sourceEdges ).newEdge + sl; 345 | edge3 = getEdge( face.c, face.a, sourceEdges ).newEdge + sl; 346 | 347 | // create 4 faces. 348 | 349 | newFace( newFaces, edge1, edge2, edge3 ); 350 | newFace( newFaces, face.a, edge1, edge3 ); 351 | newFace( newFaces, face.b, edge2, edge1 ); 352 | newFace( newFaces, face.c, edge3, edge2 ); 353 | 354 | // create 4 new uv's 355 | 356 | if ( hasUvs ) { 357 | 358 | uv = oldUvs[ i ]; 359 | 360 | x0 = uv[ 0 ]; 361 | x1 = uv[ 1 ]; 362 | x2 = uv[ 2 ]; 363 | 364 | x3.set( midpoint( x0.x, x1.x ), midpoint( x0.y, x1.y ) ); 365 | x4.set( midpoint( x1.x, x2.x ), midpoint( x1.y, x2.y ) ); 366 | x5.set( midpoint( x0.x, x2.x ), midpoint( x0.y, x2.y ) ); 367 | 368 | newUv( newUVs, x3, x4, x5 ); 369 | newUv( newUVs, x0, x3, x5 ); 370 | 371 | newUv( newUVs, x1, x4, x3 ); 372 | newUv( newUVs, x2, x5, x4 ); 373 | 374 | } 375 | 376 | } 377 | 378 | // Overwrite old arrays 379 | geometry.vertices = newVertices; 380 | geometry.faces = newFaces; 381 | if ( hasUvs ) geometry.faceVertexUvs[ 0 ] = newUVs; 382 | 383 | // console.log('done'); 384 | 385 | }; 386 | 387 | } )(); 388 | -------------------------------------------------------------------------------- /js/TessellateModifier.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Break faces with edges longer than maxEdgeLength 3 | * - not recursive 4 | * 5 | * @author alteredq / http://alteredqualia.com/ 6 | */ 7 | 8 | THREE.TessellateModifier = function ( maxEdgeLength ) { 9 | 10 | this.maxEdgeLength = maxEdgeLength; 11 | 12 | }; 13 | 14 | THREE.TessellateModifier.prototype.modify = function ( geometry ) { 15 | 16 | var edge; 17 | 18 | var faces = []; 19 | var faceVertexUvs = []; 20 | var maxEdgeLengthSquared = this.maxEdgeLength * this.maxEdgeLength; 21 | 22 | for ( var i = 0, il = geometry.faceVertexUvs.length; i < il; i ++ ) { 23 | 24 | faceVertexUvs[ i ] = []; 25 | 26 | } 27 | 28 | for ( var i = 0, il = geometry.faces.length; i < il; i ++ ) { 29 | 30 | var face = geometry.faces[ i ]; 31 | 32 | if ( face instanceof THREE.Face3 ) { 33 | 34 | var a = face.a; 35 | var b = face.b; 36 | var c = face.c; 37 | 38 | var va = geometry.vertices[ a ]; 39 | var vb = geometry.vertices[ b ]; 40 | var vc = geometry.vertices[ c ]; 41 | 42 | var dab = va.distanceToSquared( vb ); 43 | var dbc = vb.distanceToSquared( vc ); 44 | var dac = va.distanceToSquared( vc ); 45 | 46 | if ( dab > maxEdgeLengthSquared || dbc > maxEdgeLengthSquared || dac > maxEdgeLengthSquared ) { 47 | 48 | var m = geometry.vertices.length; 49 | 50 | var triA = face.clone(); 51 | var triB = face.clone(); 52 | 53 | if ( dab >= dbc && dab >= dac ) { 54 | 55 | var vm = va.clone(); 56 | vm.lerp( vb, 0.5 ); 57 | 58 | triA.a = a; 59 | triA.b = m; 60 | triA.c = c; 61 | 62 | triB.a = m; 63 | triB.b = b; 64 | triB.c = c; 65 | 66 | if ( face.vertexNormals.length === 3 ) { 67 | 68 | var vnm = face.vertexNormals[ 0 ].clone(); 69 | vnm.lerp( face.vertexNormals[ 1 ], 0.5 ); 70 | 71 | triA.vertexNormals[ 1 ].copy( vnm ); 72 | triB.vertexNormals[ 0 ].copy( vnm ); 73 | 74 | } 75 | 76 | if ( face.vertexColors.length === 3 ) { 77 | 78 | var vcm = face.vertexColors[ 0 ].clone(); 79 | vcm.lerp( face.vertexColors[ 1 ], 0.5 ); 80 | 81 | triA.vertexColors[ 1 ].copy( vcm ); 82 | triB.vertexColors[ 0 ].copy( vcm ); 83 | 84 | } 85 | 86 | edge = 0; 87 | 88 | } else if ( dbc >= dab && dbc >= dac ) { 89 | 90 | var vm = vb.clone(); 91 | vm.lerp( vc, 0.5 ); 92 | 93 | triA.a = a; 94 | triA.b = b; 95 | triA.c = m; 96 | 97 | triB.a = m; 98 | triB.b = c; 99 | triB.c = a; 100 | 101 | if ( face.vertexNormals.length === 3 ) { 102 | 103 | var vnm = face.vertexNormals[ 1 ].clone(); 104 | vnm.lerp( face.vertexNormals[ 2 ], 0.5 ); 105 | 106 | triA.vertexNormals[ 2 ].copy( vnm ); 107 | 108 | triB.vertexNormals[ 0 ].copy( vnm ); 109 | triB.vertexNormals[ 1 ].copy( face.vertexNormals[ 2 ] ); 110 | triB.vertexNormals[ 2 ].copy( face.vertexNormals[ 0 ] ); 111 | 112 | } 113 | 114 | if ( face.vertexColors.length === 3 ) { 115 | 116 | var vcm = face.vertexColors[ 1 ].clone(); 117 | vcm.lerp( face.vertexColors[ 2 ], 0.5 ); 118 | 119 | triA.vertexColors[ 2 ].copy( vcm ); 120 | 121 | triB.vertexColors[ 0 ].copy( vcm ); 122 | triB.vertexColors[ 1 ].copy( face.vertexColors[ 2 ] ); 123 | triB.vertexColors[ 2 ].copy( face.vertexColors[ 0 ] ); 124 | 125 | } 126 | 127 | edge = 1; 128 | 129 | } else { 130 | 131 | var vm = va.clone(); 132 | vm.lerp( vc, 0.5 ); 133 | 134 | triA.a = a; 135 | triA.b = b; 136 | triA.c = m; 137 | 138 | triB.a = m; 139 | triB.b = b; 140 | triB.c = c; 141 | 142 | if ( face.vertexNormals.length === 3 ) { 143 | 144 | var vnm = face.vertexNormals[ 0 ].clone(); 145 | vnm.lerp( face.vertexNormals[ 2 ], 0.5 ); 146 | 147 | triA.vertexNormals[ 2 ].copy( vnm ); 148 | triB.vertexNormals[ 0 ].copy( vnm ); 149 | 150 | } 151 | 152 | if ( face.vertexColors.length === 3 ) { 153 | 154 | var vcm = face.vertexColors[ 0 ].clone(); 155 | vcm.lerp( face.vertexColors[ 2 ], 0.5 ); 156 | 157 | triA.vertexColors[ 2 ].copy( vcm ); 158 | triB.vertexColors[ 0 ].copy( vcm ); 159 | 160 | } 161 | 162 | edge = 2; 163 | 164 | } 165 | 166 | faces.push( triA, triB ); 167 | geometry.vertices.push( vm ); 168 | 169 | for ( var j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) { 170 | 171 | if ( geometry.faceVertexUvs[ j ].length ) { 172 | 173 | var uvs = geometry.faceVertexUvs[ j ][ i ]; 174 | 175 | var uvA = uvs[ 0 ]; 176 | var uvB = uvs[ 1 ]; 177 | var uvC = uvs[ 2 ]; 178 | 179 | // AB 180 | 181 | if ( edge === 0 ) { 182 | 183 | var uvM = uvA.clone(); 184 | uvM.lerp( uvB, 0.5 ); 185 | 186 | var uvsTriA = [ uvA.clone(), uvM.clone(), uvC.clone() ]; 187 | var uvsTriB = [ uvM.clone(), uvB.clone(), uvC.clone() ]; 188 | 189 | // BC 190 | 191 | } else if ( edge === 1 ) { 192 | 193 | var uvM = uvB.clone(); 194 | uvM.lerp( uvC, 0.5 ); 195 | 196 | var uvsTriA = [ uvA.clone(), uvB.clone(), uvM.clone() ]; 197 | var uvsTriB = [ uvM.clone(), uvC.clone(), uvA.clone() ]; 198 | 199 | // AC 200 | 201 | } else { 202 | 203 | var uvM = uvA.clone(); 204 | uvM.lerp( uvC, 0.5 ); 205 | 206 | var uvsTriA = [ uvA.clone(), uvB.clone(), uvM.clone() ]; 207 | var uvsTriB = [ uvM.clone(), uvB.clone(), uvC.clone() ]; 208 | 209 | } 210 | 211 | faceVertexUvs[ j ].push( uvsTriA, uvsTriB ); 212 | 213 | } 214 | 215 | } 216 | 217 | } else { 218 | 219 | faces.push( face ); 220 | 221 | for ( var j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) { 222 | 223 | faceVertexUvs[ j ].push( geometry.faceVertexUvs[ j ][ i ] ); 224 | 225 | } 226 | 227 | } 228 | 229 | } 230 | 231 | } 232 | 233 | geometry.faces = faces; 234 | geometry.faceVertexUvs = faceVertexUvs; 235 | 236 | }; 237 | -------------------------------------------------------------------------------- /js/noise.js: -------------------------------------------------------------------------------- 1 | 2 | // ======== 1D Noise ======== 3 | function hash(x) { 4 | var nx = x*1.380251; 5 | var n = Math.floor(nx); 6 | var f = nx - n; 7 | var h = 355.347391*f+n*5.3794610581+41.53823; 8 | h = h*h+f*h+f*f*37.3921539+0.3861203; 9 | var nf = Math.floor(h); 10 | return h - nf; 11 | } 12 | 13 | function smoothNoise(x) { 14 | var n = Math.floor(x); 15 | var f = x - n; 16 | var n2 = n + 1; 17 | var h1 = hash(n); 18 | var h2 = hash(n2); 19 | smooth = f*f*(3-2*f); 20 | return h1*(1-smooth)+h2*smooth; 21 | } 22 | 23 | function fractalNoise(x) { 24 | 25 | var p = x + 11.3951031; 26 | var amp = 0.7; 27 | var scale = 10.0; 28 | var result = 0.0; 29 | for (var i = 0; i<6; i++) { 30 | result += amp*smoothNoise(p*scale); 31 | amp *= 0.5; 32 | scale *= 2.0; 33 | } 34 | 35 | return result; 36 | } 37 | -------------------------------------------------------------------------------- /js/simplexnoise.js: -------------------------------------------------------------------------------- 1 | /*! 2 | SimplexNoise 1.1.0 3 | Epistemex 2014-2016 4 | PUBLIC DOMAIN 5 | */ 6 | 7 | "use strict"; 8 | 9 | /** 10 | * Create an instance, then call noise3D with normalized x, y and z 11 | * values. 12 | * 13 | * @param {*} [seedArray] - optional seed-array to reconstruct previous random patterns. 14 | * See seedArray() method to obtain current, or create random values [0,255] for 256 indexes. 15 | * @constructor 16 | */ 17 | function SimplexNoise(seedArray) { 18 | 19 | this.perm = new Uint8Array(512); 20 | this.perm12 = new Uint8Array(512); 21 | 22 | // Initialize 23 | this.seed(seedArray); 24 | } 25 | 26 | /** 27 | * Get a noise value for this position in 3D space. Use normalized 28 | * values - you can scale the values to get more details. Use z=0 to 29 | * get a 2D value. 30 | * 31 | * NOTE: This implementation will return a value between 32 | * 0 and 1 and NOT -1 to 1. 33 | * 34 | * @param {number} x - x 35 | * @param {number} y - y 36 | * @param {number} z - z 37 | * @returns {number} normalized value [0, 1] 38 | */ 39 | SimplexNoise.prototype = { 40 | 41 | /** 42 | * Every triple padded to 4 so we can use shift op. 43 | * @private 44 | */ 45 | grad: new Int8Array([1,1,0,0, -1,1,0,0, 1,-1,0,0, -1,-1,0,0, 1,0,1,0, -1,0,1,0, 1,0,-1,0, -1,0,-1,0, 0,1,1,0, 0,-1,1,0, 0,1,-1,0, 0,-1,-1,0]), 46 | 47 | /** 48 | * Create a new noise value based on x, y and z. Typically normalized but not limited to (ie. scale). 49 | * 50 | * @param {number} x - Position on x using current permutation. 51 | * @param {number} y - Position on y using current permutation. 52 | * @param {number} z - Position on z using current permutation. Use 0 for 2D usage. 53 | * @returns {number} Note: This implementation returns a normalized value [0.0, 1.0] 54 | */ 55 | noise3D: function(x, y, z) { 56 | 57 | var s = (x + y + z) * 0.33333333333, 58 | 59 | i = (x + s)|0, 60 | j = (y + s)|0, 61 | k = (z + s)|0, 62 | 63 | t = (i + j + k) * 0.16666666667, 64 | 65 | x0 = x - (i - t), 66 | y0 = y - (j - t), 67 | z0 = z - (k - t), 68 | 69 | ii = i & 255, 70 | jj = j & 255, 71 | kk = k & 255, 72 | 73 | x1, y1, z1, 74 | x2, y2, z2, 75 | x3, y3, z3, 76 | 77 | i1, j1, k1, 78 | i2, j2, k2, 79 | 80 | n = 0, 81 | t0, t1, t2, t3, 82 | g0, g1, g2, g3, 83 | 84 | grad = this.grad, 85 | perm = this.perm, 86 | perm12 = this.perm12; 87 | 88 | if (x0 >= y0) { 89 | if(y0 >= z0) { 90 | i1 = i2 = j2 = 1; 91 | j1 = k1 = k2 = 0; 92 | } // XYZ 93 | else if(x0 >= z0) { 94 | i1 = i2 = k2 = 1; 95 | j1 = k1 = j2 = 0; 96 | } // XZY 97 | else { 98 | i1 = j1 = j2 = 0; 99 | k1 = i2 = k2 = 1; 100 | } // ZXY 101 | } 102 | else { 103 | if (y0 < z0) { 104 | i1 = i2 = j1 = 0; 105 | k1 = j2 = k2 = 1; 106 | } // ZYX 107 | else if (x0 < z0) { 108 | i1 = k1 = i2 = 0; 109 | j1 = j2 = k2 = 1; 110 | } // YZX 111 | else { 112 | i1 = k1 = k2 = 0; 113 | j1 = i2 = j2 = 1; 114 | } // YXZ 115 | } 116 | 117 | x1 = x0 - i1 + 0.16666666667; 118 | y1 = y0 - j1 + 0.16666666667; 119 | z1 = z0 - k1 + 0.16666666667; 120 | 121 | x2 = x0 - i2 + 0.33333333333; 122 | y2 = y0 - j2 + 0.33333333333; 123 | z2 = z0 - k2 + 0.33333333333; 124 | 125 | x3 = x0 - 0.5; 126 | y3 = y0 - 0.5; 127 | z3 = z0 - 0.5; 128 | 129 | g0 = perm12[ii + perm[jj + perm[kk ]]]; 130 | g1 = perm12[ii + i1 + perm[jj + j1 + perm[kk+k1]]]; 131 | g2 = perm12[ii + i2 + perm[jj + j2 + perm[kk+k2]]]; 132 | g3 = perm12[ii + 1 + perm[jj + 1 + perm[kk+ 1]]]; 133 | 134 | t0 = 0.6 - (x0*x0 + y0*y0 + z0*z0); 135 | t1 = 0.6 - (x1*x1 + y1*y1 + z1*z1); 136 | t2 = 0.6 - (x2*x2 + y2*y2 + z2*z2); 137 | t3 = 0.6 - (x3*x3 + y3*y3 + z3*z3); 138 | 139 | if (t0 >= 0) { 140 | t0 *= t0; 141 | n += t0 * t0 * dot(grad, g0, x0, y0, z0); 142 | } 143 | 144 | if (t1 >= 0) { 145 | t1 *= t1; 146 | n += t1 * t1 * dot(grad, g1, x1, y1, z1); 147 | } 148 | 149 | if (t2 >= 0) { 150 | t2 *= t2; 151 | n += t2 * t2 * dot(grad, g2, x2, y2, z2); 152 | } 153 | 154 | if (t3 >= 0) { 155 | t3 *= t3; 156 | n += t3 * t3 * dot(grad, g3, x3, y3, z3); 157 | } 158 | 159 | function dot(g, i, x, y, z) {return g[i] * x + g[i+1] * y + g[i+2] * z} 160 | 161 | return 16 * n + 0.5; //[0, 1] 162 | }, 163 | 164 | /** 165 | * Return current seed-array holding 256 indexes with values in the range [0, 255] 166 | * @returns {Uint8Array} 167 | */ 168 | getSeedArray: function() {return this.perm.subarray(0, 255)}, 169 | 170 | /** 171 | * Set new seed array or create a new random permutation. 172 | * @param {*} [seedArray] - Array holding 256 indexes with random values in the range [0, 255]. If not given, new random values will be generated. 173 | */ 174 | seed: function(seedArray) { 175 | // permutations x2 176 | for (var i = 0; i < 256; i++) { 177 | this.perm[i] = this.perm[i + 256] = seedArray ? seedArray[i] : Math.random() * 256; 178 | this.perm12[i] = this.perm12[i + 256] = this.perm[i] % 12 << 2; 179 | } 180 | } 181 | }; 182 | 183 | // Node support 184 | if (typeof exports !== "undefined") exports.SimplexNoise = SimplexNoise; -------------------------------------------------------------------------------- /js/stats.min.js: -------------------------------------------------------------------------------- 1 | // stats.js - http://github.com/mrdoob/stats.js 2 | (function(f,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"===typeof define&&define.amd?define(e):f.Stats=e()})(this,function(){var f=function(){function e(a){c.appendChild(a.dom);return a}function u(a){for(var d=0;dg+1E3&&(r.update(1E3*a/(c-g),100),g=c,a=0,t)){var d=performance.memory;t.update(d.usedJSHeapSize/ 4 | 1048576,d.jsHeapSizeLimit/1048576)}return c},update:function(){k=this.end()},domElement:c,setMode:u}};f.Panel=function(e,f,l){var c=Infinity,k=0,g=Math.round,a=g(window.devicePixelRatio||1),r=80*a,h=48*a,t=3*a,v=2*a,d=3*a,m=15*a,n=74*a,p=30*a,q=document.createElement("canvas");q.width=r;q.height=h;q.style.cssText="width:80px;height:48px";var b=q.getContext("2d");b.font="bold "+9*a+"px Helvetica,Arial,sans-serif";b.textBaseline="top";b.fillStyle=l;b.fillRect(0,0,r,h);b.fillStyle=f;b.fillText(e,t,v); 5 | b.fillRect(d,m,n,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d,m,n,p);return{dom:q,update:function(h,w){c=Math.min(c,h);k=Math.max(k,h);b.fillStyle=l;b.globalAlpha=1;b.fillRect(0,0,r,m);b.fillStyle=f;b.fillText(g(h)+" "+e+" ("+g(c)+"-"+g(k)+")",t,v);b.drawImage(q,d+a,m,n-a,p,d,m,n-a,p);b.fillRect(d+n-a,m,a,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d+n-a,m,a,g((1-h/w)*p))}}};return f}); -------------------------------------------------------------------------------- /server2.py: -------------------------------------------------------------------------------- 1 | import SimpleHTTPServer 2 | import SocketServer 3 | 4 | PORT = 8000 5 | 6 | Handler = SimpleHTTPServer.SimpleHTTPRequestHandler 7 | 8 | httpd = SocketServer.TCPServer(("", PORT), Handler) 9 | 10 | print "serving at port", PORT 11 | httpd.serve_forever() 12 | -------------------------------------------------------------------------------- /server3.py: -------------------------------------------------------------------------------- 1 | import http.server 2 | import socketserver 3 | 4 | PORT = 8000 5 | 6 | Handler = http.server.SimpleHTTPRequestHandler 7 | 8 | httpd = socketserver.TCPServer(("", PORT), Handler) 9 | print("serving at port", PORT) 10 | httpd.serve_forever() 11 | -------------------------------------------------------------------------------- /textures/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/textures/Thumbs.db -------------------------------------------------------------------------------- /textures/lava/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/textures/lava/Thumbs.db -------------------------------------------------------------------------------- /textures/lava/lavatile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/textures/lava/lavatile.jpg -------------------------------------------------------------------------------- /textures/starbucks/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/textures/starbucks/Thumbs.db -------------------------------------------------------------------------------- /textures/starbucks/bumpmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/textures/starbucks/bumpmap.jpg -------------------------------------------------------------------------------- /textures/starbucks/sb3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/textures/starbucks/sb3.jpg -------------------------------------------------------------------------------- /textures/starbucks/wood.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/textures/starbucks/wood.jpg -------------------------------------------------------------------------------- /textures/waternormals.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Computer-Graphics-And-Pretty-Pictures/CGPP-Projects/394fb0d9422af956564cfbebe236781e463b1b32/textures/waternormals.jpg -------------------------------------------------------------------------------- /webgl-modifier-tessellation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | three.js webgl - modifier - tessellation 5 | 6 | 7 | 29 | 30 | 31 | 32 | 33 |
34 | 35 | 36 | 37 | 38 | 39 | 40 | 62 | 63 | 85 | 86 | 87 | 263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 | 357 | HELLLOOOO 358 | 359 | 360 | 361 | 362 | -------------------------------------------------------------------------------- /week1_w17/AudioBasic.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | three.js webgl - geometry hierarchy 2 5 | 6 | 7 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 129 | 130 | -------------------------------------------------------------------------------- /week1_w17/AudioStarterKit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | three.js webgl - geometry hierarchy 2 5 | 6 | 7 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 166 | 167 | -------------------------------------------------------------------------------- /week1_w17/AudioStarterKit2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | three.js webgl - geometry hierarchy 2 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 28 | 29 | 211 | 212 | --------------------------------------------------------------------------------