├── README.md ├── libs ├── AsciiEffect.js ├── CTMLoader.js ├── CTMWorker.js ├── ColladaLoader.js ├── ConvexGeometry.js ├── CopyShader.js ├── EffectComposer.js ├── FXAAShader.js ├── FirstPersonControls.js ├── FlyControls.js ├── GeometryExporter.js ├── JSONLoader.js ├── JSONLoader_old.js ├── MD2Character.js ├── MTLLoader.js ├── MaskPass.js ├── OBJLoader.js ├── OBJMTLLoader.js ├── OrbitControls.js ├── PDBLoader.js ├── PLYLoader.js ├── ParametricGeometries.js ├── PathControls.js ├── RenderPass.js ├── RollControls.js ├── STLLoader.js ├── SceneExporter.js ├── SceneLoader.js ├── ShaderDeferred.js ├── ShaderPass.js ├── ThreeBSP.coffee ├── ThreeBSP.js ├── TrackballControls.js ├── VTKLoader.js ├── WebGLDeferredRenderer.js ├── ammo.js ├── chroma.js ├── coffee-script.js ├── ctm.js ├── d3-threeD.js ├── dat.gui.js ├── jquery-1.9.0.js ├── literally │ ├── css │ │ └── literally.css │ ├── img │ │ ├── alpha.png │ │ ├── eraser.png │ │ ├── eyedropper.png │ │ ├── hue.png │ │ ├── line.png │ │ ├── pan.png │ │ ├── pencil.png │ │ ├── rectangle.png │ │ ├── saturation.png │ │ └── screenshot.png │ ├── jquery-1.8.2.js │ ├── js │ │ ├── literallycanvas.js │ │ └── literallycanvas.min.js │ └── underscore-1.4.2.js ├── lzma.js ├── perlin.js ├── physi.js ├── physijs_worker.js ├── postprocessing │ ├── BloomPass.js │ ├── DotScreenPass.js │ ├── EffectComposer.js │ ├── FilmPass.js │ ├── MaskPass.js │ ├── RenderPass.js │ ├── SavePass.js │ ├── ShaderPass.js │ └── TexturePass.js ├── shaders │ ├── BasicShader.js │ ├── BleachBypassShader.js │ ├── BlendShader.js │ ├── BokehShader.js │ ├── BrightnessContrastShader.js │ ├── ColorCorrectionShader.js │ ├── ColorifyShader.js │ ├── ConvolutionShader.js │ ├── CopyShader.js │ ├── DOFMipMapShader.js │ ├── DotScreenShader.js │ ├── EdgeShader.js │ ├── EdgeShader2.js │ ├── FXAAShader.js │ ├── FilmShader.js │ ├── FocusShader.js │ ├── FresnelShader.js │ ├── HorizontalBlurShader.js │ ├── HorizontalTiltShiftShader.js │ ├── HueSaturationShader.js │ ├── KaleidoShader.js │ ├── LuminosityShader.js │ ├── MirrorShader.js │ ├── NormalMapShader.js │ ├── RGBShiftShader.js │ ├── SSAOShader.js │ ├── SepiaShader.js │ ├── TriangleBlurShader.js │ ├── UnpackDepthRGBAShader.js │ ├── VerticalBlurShader.js │ ├── VerticalTiltShiftShader.js │ └── VignetteShader.js ├── sketch.js ├── spin.js ├── stats.js ├── three.js └── tween.min.js ├── moon-buggy ├── Main.js ├── index.html └── resources │ ├── background.png │ ├── body.png │ ├── earth.png │ ├── giraffe.png │ ├── lion.png │ ├── penguin.png │ ├── rainbow.png │ ├── weemee.png │ └── wheel.png ├── tunnel-1 ├── .DS_Store ├── Main.js ├── index.html └── particle.png ├── tunnel-2 ├── Main.js ├── index.html └── particle.png └── tunnel-3 ├── .DS_Store ├── Bullet.js ├── Earth.js ├── Highway.js ├── Main.js ├── Obstacle.js ├── Skybox.js ├── Spaceship.js ├── index.html ├── misc.js ├── resources ├── .DS_Store ├── cubemap │ ├── .DS_Store │ ├── negx.jpg │ ├── negy.jpg │ ├── negz.jpg │ ├── posx.jpg │ ├── posy.jpg │ └── posz.jpg ├── earth │ ├── .DS_Store │ ├── Earth.png │ ├── EarthNormal.png │ └── EarthSpec.png ├── particle.png ├── spaceship │ ├── spaceship.mtl │ └── spaceship.obj └── ui │ ├── .DS_Store │ ├── boost-key.png │ ├── rotate-left-key.png │ ├── rotate-right-key.png │ ├── shoot-key.png │ └── spinner.png └── styles.css /README.md: -------------------------------------------------------------------------------- 1 | threejs-experiments 2 | =================== 3 | 4 | A collection of three.js experiments by *[Christopher Caleb](http://www.yeahbutisitflash.com/?page_id=2)*. 5 | 6 | *[Tunnel 1](http://www.yeahbutisitflash.com/?p=6528)* 7 | 8 | *[Tunnel 2](http://www.yeahbutisitflash.com/?p=6528)* 9 | 10 | *[Tunnel 3](http://www.yeahbutisitflash.com/?p=6557)* 11 | 12 | *[Moon Buggy](http://www.yeahbutisitflash.com/?p=7105)* 13 | -------------------------------------------------------------------------------- /libs/CTMWorker.js: -------------------------------------------------------------------------------- 1 | 2 | self.onmessage = function( event ) { 3 | 4 | var files = []; 5 | 6 | for ( var i = 0; i < event.data.offsets.length; i ++ ) { 7 | 8 | var stream = new CTM.Stream( event.data.data ); 9 | stream.offset = event.data.offsets[ i ]; 10 | 11 | files[ i ] = new CTM.File( stream ); 12 | 13 | } 14 | 15 | self.postMessage( files ); 16 | self.close(); 17 | 18 | } -------------------------------------------------------------------------------- /libs/ConvexGeometry.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author qiao / https://github.com/qiao 3 | * @fileoverview This is a convex hull generator using the incremental method. 4 | * The complexity is O(n^2) where n is the number of vertices. 5 | * O(nlogn) algorithms do exist, but they are much more complicated. 6 | * 7 | * Benchmark: 8 | * 9 | * Platform: CPU: P7350 @2.00GHz Engine: V8 10 | * 11 | * Num Vertices Time(ms) 12 | * 13 | * 10 1 14 | * 20 3 15 | * 30 19 16 | * 40 48 17 | * 50 107 18 | */ 19 | 20 | THREE.ConvexGeometry = function( vertices ) { 21 | 22 | THREE.Geometry.call( this ); 23 | 24 | var faces = [ [ 0, 1, 2 ], [ 0, 2, 1 ] ]; 25 | 26 | for ( var i = 3; i < vertices.length; i++ ) { 27 | 28 | addPoint( i ); 29 | 30 | } 31 | 32 | 33 | function addPoint( vertexId ) { 34 | 35 | var vertex = vertices[ vertexId ].clone(); 36 | 37 | var mag = vertex.length(); 38 | vertex.x += mag * randomOffset(); 39 | vertex.y += mag * randomOffset(); 40 | vertex.z += mag * randomOffset(); 41 | 42 | var hole = []; 43 | 44 | for ( var f = 0; f < faces.length; ) { 45 | 46 | var face = faces[ f ]; 47 | 48 | // for each face, if the vertex can see it, 49 | // then we try to add the face's edges into the hole. 50 | if ( visible( face, vertex ) ) { 51 | 52 | for ( var e = 0; e < 3; e++ ) { 53 | 54 | var edge = [ face[ e ], face[ ( e + 1 ) % 3 ] ]; 55 | var boundary = true; 56 | 57 | // remove duplicated edges. 58 | for ( var h = 0; h < hole.length; h++ ) { 59 | 60 | if ( equalEdge( hole[ h ], edge ) ) { 61 | 62 | hole[ h ] = hole[ hole.length - 1 ]; 63 | hole.pop(); 64 | boundary = false; 65 | break; 66 | 67 | } 68 | 69 | } 70 | 71 | if ( boundary ) { 72 | 73 | hole.push( edge ); 74 | 75 | } 76 | 77 | } 78 | 79 | // remove faces[ f ] 80 | faces[ f ] = faces[ faces.length - 1 ]; 81 | faces.pop(); 82 | 83 | } else { // not visible 84 | 85 | f++; 86 | 87 | } 88 | } 89 | 90 | // construct the new faces formed by the edges of the hole and the vertex 91 | for ( var h = 0; h < hole.length; h++ ) { 92 | 93 | faces.push( [ 94 | hole[ h ][ 0 ], 95 | hole[ h ][ 1 ], 96 | vertexId 97 | ] ); 98 | 99 | } 100 | } 101 | 102 | /** 103 | * Whether the face is visible from the vertex 104 | */ 105 | function visible( face, vertex ) { 106 | 107 | var va = vertices[ face[ 0 ] ]; 108 | var vb = vertices[ face[ 1 ] ]; 109 | var vc = vertices[ face[ 2 ] ]; 110 | 111 | var n = normal( va, vb, vc ); 112 | 113 | // distance from face to origin 114 | var dist = n.dot( va ); 115 | 116 | return n.dot( vertex ) >= dist; 117 | 118 | } 119 | 120 | /** 121 | * Face normal 122 | */ 123 | function normal( va, vb, vc ) { 124 | 125 | var cb = new THREE.Vector3(); 126 | var ab = new THREE.Vector3(); 127 | 128 | cb.subVectors( vc, vb ); 129 | ab.subVectors( va, vb ); 130 | cb.cross( ab ); 131 | 132 | cb.normalize(); 133 | 134 | return cb; 135 | 136 | } 137 | 138 | /** 139 | * Detect whether two edges are equal. 140 | * Note that when constructing the convex hull, two same edges can only 141 | * be of the negative direction. 142 | */ 143 | function equalEdge( ea, eb ) { 144 | 145 | return ea[ 0 ] === eb[ 1 ] && ea[ 1 ] === eb[ 0 ]; 146 | 147 | } 148 | 149 | /** 150 | * Create a random offset between -1e-6 and 1e-6. 151 | */ 152 | function randomOffset() { 153 | 154 | return ( Math.random() - 0.5 ) * 2 * 1e-6; 155 | 156 | } 157 | 158 | 159 | /** 160 | * XXX: Not sure if this is the correct approach. Need someone to review. 161 | */ 162 | function vertexUv( vertex ) { 163 | 164 | var mag = vertex.length(); 165 | return new THREE.Vector2( vertex.x / mag, vertex.y / mag ); 166 | 167 | } 168 | 169 | // Push vertices into `this.vertices`, skipping those inside the hull 170 | var id = 0; 171 | var newId = new Array( vertices.length ); // map from old vertex id to new id 172 | 173 | for ( var i = 0; i < faces.length; i++ ) { 174 | 175 | var face = faces[ i ]; 176 | 177 | for ( var j = 0; j < 3; j++ ) { 178 | 179 | if ( newId[ face[ j ] ] === undefined ) { 180 | 181 | newId[ face[ j ] ] = id++; 182 | this.vertices.push( vertices[ face[ j ] ] ); 183 | 184 | } 185 | 186 | face[ j ] = newId[ face[ j ] ]; 187 | 188 | } 189 | 190 | } 191 | 192 | // Convert faces into instances of THREE.Face3 193 | for ( var i = 0; i < faces.length; i++ ) { 194 | 195 | this.faces.push( new THREE.Face3( 196 | faces[ i ][ 0 ], 197 | faces[ i ][ 1 ], 198 | faces[ i ][ 2 ] 199 | ) ); 200 | 201 | } 202 | 203 | // Compute UVs 204 | for ( var i = 0; i < this.faces.length; i++ ) { 205 | 206 | var face = this.faces[ i ]; 207 | 208 | this.faceVertexUvs[ 0 ].push( [ 209 | vertexUv( this.vertices[ face.a ] ), 210 | vertexUv( this.vertices[ face.b ] ), 211 | vertexUv( this.vertices[ face.c ]) 212 | ] ); 213 | 214 | } 215 | 216 | 217 | this.computeCentroids(); 218 | this.computeFaceNormals(); 219 | this.computeVertexNormals(); 220 | 221 | }; 222 | 223 | THREE.ConvexGeometry.prototype = Object.create( THREE.Geometry.prototype ); 224 | -------------------------------------------------------------------------------- /libs/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": { type: "t", value: null }, 12 | "opacity": { type: "f", 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 | -------------------------------------------------------------------------------- /libs/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 width = window.innerWidth || 1; 12 | var height = window.innerHeight || 1; 13 | var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false }; 14 | 15 | renderTarget = new THREE.WebGLRenderTarget( width, height, parameters ); 16 | 17 | } 18 | 19 | this.renderTarget1 = renderTarget; 20 | this.renderTarget2 = renderTarget.clone(); 21 | 22 | this.writeBuffer = this.renderTarget1; 23 | this.readBuffer = this.renderTarget2; 24 | 25 | this.passes = []; 26 | 27 | if ( THREE.CopyShader === undefined ) 28 | console.error( "THREE.EffectComposer relies on THREE.CopyShader" ); 29 | 30 | this.copyPass = new THREE.ShaderPass( THREE.CopyShader ); 31 | 32 | }; 33 | 34 | THREE.EffectComposer.prototype = { 35 | 36 | swapBuffers: function() { 37 | 38 | var tmp = this.readBuffer; 39 | this.readBuffer = this.writeBuffer; 40 | this.writeBuffer = tmp; 41 | 42 | }, 43 | 44 | addPass: function ( pass ) { 45 | 46 | this.passes.push( pass ); 47 | 48 | }, 49 | 50 | insertPass: function ( pass, index ) { 51 | 52 | this.passes.splice( index, 0, pass ); 53 | 54 | }, 55 | 56 | render: function ( delta ) { 57 | 58 | this.writeBuffer = this.renderTarget1; 59 | this.readBuffer = this.renderTarget2; 60 | 61 | var maskActive = false; 62 | 63 | var pass, i, il = this.passes.length; 64 | 65 | for ( i = 0; i < il; i ++ ) { 66 | 67 | pass = this.passes[ i ]; 68 | 69 | if ( !pass.enabled ) continue; 70 | 71 | pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive ); 72 | 73 | if ( pass.needsSwap ) { 74 | 75 | if ( maskActive ) { 76 | 77 | var context = this.renderer.context; 78 | 79 | context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff ); 80 | 81 | this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta ); 82 | 83 | context.stencilFunc( context.EQUAL, 1, 0xffffffff ); 84 | 85 | } 86 | 87 | this.swapBuffers(); 88 | 89 | } 90 | 91 | if ( pass instanceof THREE.MaskPass ) { 92 | 93 | maskActive = true; 94 | 95 | } else if ( pass instanceof THREE.ClearMaskPass ) { 96 | 97 | maskActive = false; 98 | 99 | } 100 | 101 | } 102 | 103 | }, 104 | 105 | reset: function ( renderTarget ) { 106 | 107 | if ( renderTarget === undefined ) { 108 | 109 | renderTarget = this.renderTarget1.clone(); 110 | 111 | renderTarget.width = window.innerWidth; 112 | renderTarget.height = window.innerHeight; 113 | 114 | } 115 | 116 | this.renderTarget1 = renderTarget; 117 | this.renderTarget2 = renderTarget.clone(); 118 | 119 | this.writeBuffer = this.renderTarget1; 120 | this.readBuffer = this.renderTarget2; 121 | 122 | }, 123 | 124 | setSize: function ( width, height ) { 125 | 126 | var renderTarget = this.renderTarget1.clone(); 127 | 128 | renderTarget.width = width; 129 | renderTarget.height = height; 130 | 131 | this.reset( renderTarget ); 132 | 133 | } 134 | 135 | }; 136 | 137 | // shared ortho camera 138 | 139 | THREE.EffectComposer.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 ); 140 | 141 | THREE.EffectComposer.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null ); 142 | 143 | THREE.EffectComposer.scene = new THREE.Scene(); 144 | THREE.EffectComposer.scene.add( THREE.EffectComposer.quad ); 145 | -------------------------------------------------------------------------------- /libs/FXAAShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * @author davidedc / http://www.sketchpatch.net/ 4 | * 5 | * NVIDIA FXAA by Timothy Lottes 6 | * http://timothylottes.blogspot.com/2011/06/fxaa3-source-released.html 7 | * - WebGL port by @supereggbert 8 | * http://www.glge.org/demos/fxaa/ 9 | */ 10 | 11 | THREE.FXAAShader = { 12 | 13 | uniforms: { 14 | 15 | "tDiffuse": { type: "t", value: null }, 16 | "resolution": { type: "v2", value: new THREE.Vector2( 1 / 1024, 1 / 512 ) } 17 | 18 | }, 19 | 20 | vertexShader: [ 21 | 22 | "varying vec2 vUv;", 23 | 24 | "void main() {", 25 | 26 | "vUv = uv;", 27 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 28 | 29 | "}" 30 | 31 | ].join("\n"), 32 | 33 | fragmentShader: [ 34 | 35 | "uniform sampler2D tDiffuse;", 36 | "uniform vec2 resolution;", 37 | 38 | "varying vec2 vUv;", 39 | 40 | "#define FXAA_REDUCE_MIN (1.0/128.0)", 41 | "#define FXAA_REDUCE_MUL (1.0/8.0)", 42 | "#define FXAA_SPAN_MAX 8.0", 43 | 44 | "void main() {", 45 | 46 | "vec3 rgbNW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ).xyz;", 47 | "vec3 rgbNE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ).xyz;", 48 | "vec3 rgbSW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ).xyz;", 49 | "vec3 rgbSE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ).xyz;", 50 | "vec4 rgbaM = texture2D( tDiffuse, gl_FragCoord.xy * resolution );", 51 | "vec3 rgbM = rgbaM.xyz;", 52 | "float opacity = rgbaM.w;", 53 | 54 | "vec3 luma = vec3( 0.299, 0.587, 0.114 );", 55 | 56 | "float lumaNW = dot( rgbNW, luma );", 57 | "float lumaNE = dot( rgbNE, luma );", 58 | "float lumaSW = dot( rgbSW, luma );", 59 | "float lumaSE = dot( rgbSE, luma );", 60 | "float lumaM = dot( rgbM, luma );", 61 | "float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );", 62 | "float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );", 63 | 64 | "vec2 dir;", 65 | "dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));", 66 | "dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));", 67 | 68 | "float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );", 69 | 70 | "float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );", 71 | "dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),", 72 | "max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),", 73 | "dir * rcpDirMin)) * resolution;", 74 | 75 | "vec3 rgbA = 0.5 * (", 76 | "texture2D( tDiffuse, gl_FragCoord.xy * resolution + dir * ( 1.0 / 3.0 - 0.5 ) ).xyz +", 77 | "texture2D( tDiffuse, gl_FragCoord.xy * resolution + dir * ( 2.0 / 3.0 - 0.5 ) ).xyz );", 78 | 79 | "vec3 rgbB = rgbA * 0.5 + 0.25 * (", 80 | "texture2D( tDiffuse, gl_FragCoord.xy * resolution + dir * -0.5 ).xyz +", 81 | "texture2D( tDiffuse, gl_FragCoord.xy * resolution + dir * 0.5 ).xyz );", 82 | 83 | "float lumaB = dot( rgbB, luma );", 84 | 85 | "if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) {", 86 | 87 | "gl_FragColor = vec4( rgbA, opacity );", 88 | 89 | "} else {", 90 | 91 | "gl_FragColor = vec4( rgbB, opacity );", 92 | 93 | "}", 94 | 95 | "}" 96 | 97 | ].join("\n") 98 | 99 | }; 100 | -------------------------------------------------------------------------------- /libs/FirstPersonControls.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | * @author paulirish / http://paulirish.com/ 5 | */ 6 | 7 | THREE.FirstPersonControls = function ( object, domElement ) { 8 | 9 | this.object = object; 10 | this.target = new THREE.Vector3( 0, 0, 0 ); 11 | 12 | this.domElement = ( domElement !== undefined ) ? domElement : document; 13 | 14 | this.movementSpeed = 1.0; 15 | this.lookSpeed = 0.005; 16 | 17 | this.lookVertical = true; 18 | this.autoForward = false; 19 | // this.invertVertical = false; 20 | 21 | this.activeLook = true; 22 | 23 | this.heightSpeed = false; 24 | this.heightCoef = 1.0; 25 | this.heightMin = 0.0; 26 | this.heightMax = 1.0; 27 | 28 | this.constrainVertical = false; 29 | this.verticalMin = 0; 30 | this.verticalMax = Math.PI; 31 | 32 | this.autoSpeedFactor = 0.0; 33 | 34 | this.mouseX = 0; 35 | this.mouseY = 0; 36 | 37 | this.lat = 0; 38 | this.lon = 0; 39 | this.phi = 0; 40 | this.theta = 0; 41 | 42 | this.moveForward = false; 43 | this.moveBackward = false; 44 | this.moveLeft = false; 45 | this.moveRight = false; 46 | this.freeze = false; 47 | 48 | this.mouseDragOn = false; 49 | 50 | this.viewHalfX = 0; 51 | this.viewHalfY = 0; 52 | 53 | if ( this.domElement !== document ) { 54 | 55 | this.domElement.setAttribute( 'tabindex', -1 ); 56 | 57 | } 58 | 59 | // 60 | 61 | this.handleResize = function () { 62 | 63 | if ( this.domElement === document ) { 64 | 65 | this.viewHalfX = window.innerWidth / 2; 66 | this.viewHalfY = window.innerHeight / 2; 67 | 68 | } else { 69 | 70 | this.viewHalfX = this.domElement.offsetWidth / 2; 71 | this.viewHalfY = this.domElement.offsetHeight / 2; 72 | 73 | } 74 | 75 | }; 76 | 77 | this.onMouseDown = function ( event ) { 78 | 79 | if ( this.domElement !== document ) { 80 | 81 | this.domElement.focus(); 82 | 83 | } 84 | 85 | event.preventDefault(); 86 | event.stopPropagation(); 87 | 88 | if ( this.activeLook ) { 89 | 90 | switch ( event.button ) { 91 | 92 | case 0: this.moveForward = true; break; 93 | case 2: this.moveBackward = true; break; 94 | 95 | } 96 | 97 | } 98 | 99 | this.mouseDragOn = true; 100 | 101 | }; 102 | 103 | this.onMouseUp = function ( event ) { 104 | 105 | event.preventDefault(); 106 | event.stopPropagation(); 107 | 108 | if ( this.activeLook ) { 109 | 110 | switch ( event.button ) { 111 | 112 | case 0: this.moveForward = false; break; 113 | case 2: this.moveBackward = false; break; 114 | 115 | } 116 | 117 | } 118 | 119 | this.mouseDragOn = false; 120 | 121 | }; 122 | 123 | this.onMouseMove = function ( event ) { 124 | 125 | if ( this.domElement === document ) { 126 | 127 | this.mouseX = event.pageX - this.viewHalfX; 128 | this.mouseY = event.pageY - this.viewHalfY; 129 | 130 | } else { 131 | 132 | this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX; 133 | this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY; 134 | 135 | } 136 | 137 | }; 138 | 139 | this.onKeyDown = function ( event ) { 140 | 141 | //event.preventDefault(); 142 | 143 | switch ( event.keyCode ) { 144 | 145 | case 38: /*up*/ 146 | case 87: /*W*/ this.moveForward = true; break; 147 | 148 | case 37: /*left*/ 149 | case 65: /*A*/ this.moveLeft = true; break; 150 | 151 | case 40: /*down*/ 152 | case 83: /*S*/ this.moveBackward = true; break; 153 | 154 | case 39: /*right*/ 155 | case 68: /*D*/ this.moveRight = true; break; 156 | 157 | case 82: /*R*/ this.moveUp = true; break; 158 | case 70: /*F*/ this.moveDown = true; break; 159 | 160 | case 81: /*Q*/ this.freeze = !this.freeze; break; 161 | 162 | } 163 | 164 | }; 165 | 166 | this.onKeyUp = function ( event ) { 167 | 168 | switch( event.keyCode ) { 169 | 170 | case 38: /*up*/ 171 | case 87: /*W*/ this.moveForward = false; break; 172 | 173 | case 37: /*left*/ 174 | case 65: /*A*/ this.moveLeft = false; break; 175 | 176 | case 40: /*down*/ 177 | case 83: /*S*/ this.moveBackward = false; break; 178 | 179 | case 39: /*right*/ 180 | case 68: /*D*/ this.moveRight = false; break; 181 | 182 | case 82: /*R*/ this.moveUp = false; break; 183 | case 70: /*F*/ this.moveDown = false; break; 184 | 185 | } 186 | 187 | }; 188 | 189 | this.update = function( delta ) { 190 | 191 | if ( this.freeze ) { 192 | 193 | return; 194 | 195 | } 196 | 197 | if ( this.heightSpeed ) { 198 | 199 | var y = THREE.Math.clamp( this.object.position.y, this.heightMin, this.heightMax ); 200 | var heightDelta = y - this.heightMin; 201 | 202 | this.autoSpeedFactor = delta * ( heightDelta * this.heightCoef ); 203 | 204 | } else { 205 | 206 | this.autoSpeedFactor = 0.0; 207 | 208 | } 209 | 210 | var actualMoveSpeed = delta * this.movementSpeed; 211 | 212 | if ( this.moveForward || ( this.autoForward && !this.moveBackward ) ) this.object.translateZ( - ( actualMoveSpeed + this.autoSpeedFactor ) ); 213 | if ( this.moveBackward ) this.object.translateZ( actualMoveSpeed ); 214 | 215 | if ( this.moveLeft ) this.object.translateX( - actualMoveSpeed ); 216 | if ( this.moveRight ) this.object.translateX( actualMoveSpeed ); 217 | 218 | if ( this.moveUp ) this.object.translateY( actualMoveSpeed ); 219 | if ( this.moveDown ) this.object.translateY( - actualMoveSpeed ); 220 | 221 | var actualLookSpeed = delta * this.lookSpeed; 222 | 223 | if ( !this.activeLook ) { 224 | 225 | actualLookSpeed = 0; 226 | 227 | } 228 | 229 | var verticalLookRatio = 1; 230 | 231 | if ( this.constrainVertical ) { 232 | 233 | verticalLookRatio = Math.PI / ( this.verticalMax - this.verticalMin ); 234 | 235 | } 236 | 237 | this.lon += this.mouseX * actualLookSpeed; 238 | if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed * verticalLookRatio; 239 | 240 | this.lat = Math.max( - 85, Math.min( 85, this.lat ) ); 241 | this.phi = THREE.Math.degToRad( 90 - this.lat ); 242 | 243 | this.theta = THREE.Math.degToRad( this.lon ); 244 | 245 | if ( this.constrainVertical ) { 246 | 247 | this.phi = THREE.Math.mapLinear( this.phi, 0, Math.PI, this.verticalMin, this.verticalMax ); 248 | 249 | } 250 | 251 | var targetPosition = this.target, 252 | position = this.object.position; 253 | 254 | targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta ); 255 | targetPosition.y = position.y + 100 * Math.cos( this.phi ); 256 | targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta ); 257 | 258 | this.object.lookAt( targetPosition ); 259 | 260 | }; 261 | 262 | 263 | this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false ); 264 | 265 | this.domElement.addEventListener( 'mousemove', bind( this, this.onMouseMove ), false ); 266 | this.domElement.addEventListener( 'mousedown', bind( this, this.onMouseDown ), false ); 267 | this.domElement.addEventListener( 'mouseup', bind( this, this.onMouseUp ), false ); 268 | this.domElement.addEventListener( 'keydown', bind( this, this.onKeyDown ), false ); 269 | this.domElement.addEventListener( 'keyup', bind( this, this.onKeyUp ), false ); 270 | 271 | function bind( scope, fn ) { 272 | 273 | return function () { 274 | 275 | fn.apply( scope, arguments ); 276 | 277 | }; 278 | 279 | }; 280 | 281 | this.handleResize(); 282 | 283 | }; 284 | -------------------------------------------------------------------------------- /libs/FlyControls.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author James Baicoianu / http://www.baicoianu.com/ 3 | */ 4 | 5 | THREE.FlyControls = function ( object, domElement ) { 6 | 7 | this.object = object; 8 | 9 | this.domElement = ( domElement !== undefined ) ? domElement : document; 10 | if ( domElement ) this.domElement.setAttribute( 'tabindex', -1 ); 11 | 12 | // API 13 | 14 | this.movementSpeed = 1.0; 15 | this.rollSpeed = 0.005; 16 | 17 | this.dragToLook = false; 18 | this.autoForward = false; 19 | 20 | // disable default target object behavior 21 | 22 | // internals 23 | 24 | this.tmpQuaternion = new THREE.Quaternion(); 25 | 26 | this.mouseStatus = 0; 27 | 28 | this.moveState = { up: 0, down: 0, left: 0, right: 0, forward: 0, back: 0, pitchUp: 0, pitchDown: 0, yawLeft: 0, yawRight: 0, rollLeft: 0, rollRight: 0 }; 29 | this.moveVector = new THREE.Vector3( 0, 0, 0 ); 30 | this.rotationVector = new THREE.Vector3( 0, 0, 0 ); 31 | 32 | this.handleEvent = function ( event ) { 33 | 34 | if ( typeof this[ event.type ] == 'function' ) { 35 | 36 | this[ event.type ]( event ); 37 | 38 | } 39 | 40 | }; 41 | 42 | this.keydown = function( event ) { 43 | 44 | if ( event.altKey ) { 45 | 46 | return; 47 | 48 | } 49 | 50 | //event.preventDefault(); 51 | 52 | switch ( event.keyCode ) { 53 | 54 | case 16: /* shift */ this.movementSpeedMultiplier = .1; break; 55 | 56 | case 87: /*W*/ this.moveState.forward = 1; break; 57 | case 83: /*S*/ this.moveState.back = 1; break; 58 | 59 | case 65: /*A*/ this.moveState.left = 1; break; 60 | case 68: /*D*/ this.moveState.right = 1; break; 61 | 62 | case 82: /*R*/ this.moveState.up = 1; break; 63 | case 70: /*F*/ this.moveState.down = 1; break; 64 | 65 | case 38: /*up*/ this.moveState.pitchUp = 1; break; 66 | case 40: /*down*/ this.moveState.pitchDown = 1; break; 67 | 68 | case 37: /*left*/ this.moveState.yawLeft = 1; break; 69 | case 39: /*right*/ this.moveState.yawRight = 1; break; 70 | 71 | case 81: /*Q*/ this.moveState.rollLeft = 1; break; 72 | case 69: /*E*/ this.moveState.rollRight = 1; break; 73 | 74 | } 75 | 76 | this.updateMovementVector(); 77 | this.updateRotationVector(); 78 | 79 | }; 80 | 81 | this.keyup = function( event ) { 82 | 83 | switch( event.keyCode ) { 84 | 85 | case 16: /* shift */ this.movementSpeedMultiplier = 1; break; 86 | 87 | case 87: /*W*/ this.moveState.forward = 0; break; 88 | case 83: /*S*/ this.moveState.back = 0; break; 89 | 90 | case 65: /*A*/ this.moveState.left = 0; break; 91 | case 68: /*D*/ this.moveState.right = 0; break; 92 | 93 | case 82: /*R*/ this.moveState.up = 0; break; 94 | case 70: /*F*/ this.moveState.down = 0; break; 95 | 96 | case 38: /*up*/ this.moveState.pitchUp = 0; break; 97 | case 40: /*down*/ this.moveState.pitchDown = 0; break; 98 | 99 | case 37: /*left*/ this.moveState.yawLeft = 0; break; 100 | case 39: /*right*/ this.moveState.yawRight = 0; break; 101 | 102 | case 81: /*Q*/ this.moveState.rollLeft = 0; break; 103 | case 69: /*E*/ this.moveState.rollRight = 0; break; 104 | 105 | } 106 | 107 | this.updateMovementVector(); 108 | this.updateRotationVector(); 109 | 110 | }; 111 | 112 | this.mousedown = function( event ) { 113 | 114 | if ( this.domElement !== document ) { 115 | 116 | this.domElement.focus(); 117 | 118 | } 119 | 120 | event.preventDefault(); 121 | event.stopPropagation(); 122 | 123 | if ( this.dragToLook ) { 124 | 125 | this.mouseStatus ++; 126 | 127 | } else { 128 | 129 | switch ( event.button ) { 130 | 131 | case 0: this.moveState.forward = 1; break; 132 | case 2: this.moveState.back = 1; break; 133 | 134 | } 135 | 136 | this.updateMovementVector(); 137 | 138 | } 139 | 140 | }; 141 | 142 | this.mousemove = function( event ) { 143 | 144 | if ( !this.dragToLook || this.mouseStatus > 0 ) { 145 | 146 | var container = this.getContainerDimensions(); 147 | var halfWidth = container.size[ 0 ] / 2; 148 | var halfHeight = container.size[ 1 ] / 2; 149 | 150 | this.moveState.yawLeft = - ( ( event.pageX - container.offset[ 0 ] ) - halfWidth ) / halfWidth; 151 | this.moveState.pitchDown = ( ( event.pageY - container.offset[ 1 ] ) - halfHeight ) / halfHeight; 152 | 153 | this.updateRotationVector(); 154 | 155 | } 156 | 157 | }; 158 | 159 | this.mouseup = function( event ) { 160 | 161 | event.preventDefault(); 162 | event.stopPropagation(); 163 | 164 | if ( this.dragToLook ) { 165 | 166 | this.mouseStatus --; 167 | 168 | this.moveState.yawLeft = this.moveState.pitchDown = 0; 169 | 170 | } else { 171 | 172 | switch ( event.button ) { 173 | 174 | case 0: this.moveState.forward = 0; break; 175 | case 2: this.moveState.back = 0; break; 176 | 177 | } 178 | 179 | this.updateMovementVector(); 180 | 181 | } 182 | 183 | this.updateRotationVector(); 184 | 185 | }; 186 | 187 | this.update = function( delta ) { 188 | 189 | var moveMult = delta * this.movementSpeed; 190 | var rotMult = delta * this.rollSpeed; 191 | 192 | this.object.translateX( this.moveVector.x * moveMult ); 193 | this.object.translateY( this.moveVector.y * moveMult ); 194 | this.object.translateZ( this.moveVector.z * moveMult ); 195 | 196 | this.tmpQuaternion.set( this.rotationVector.x * rotMult, this.rotationVector.y * rotMult, this.rotationVector.z * rotMult, 1 ).normalize(); 197 | this.object.quaternion.multiply( this.tmpQuaternion ); 198 | 199 | // expose the rotation vector for convenience 200 | this.object.rotation.setFromQuaternion( this.object.quaternion, this.object.rotation.order ); 201 | 202 | 203 | }; 204 | 205 | this.updateMovementVector = function() { 206 | 207 | var forward = ( this.moveState.forward || ( this.autoForward && !this.moveState.back ) ) ? 1 : 0; 208 | 209 | this.moveVector.x = ( -this.moveState.left + this.moveState.right ); 210 | this.moveVector.y = ( -this.moveState.down + this.moveState.up ); 211 | this.moveVector.z = ( -forward + this.moveState.back ); 212 | 213 | //console.log( 'move:', [ this.moveVector.x, this.moveVector.y, this.moveVector.z ] ); 214 | 215 | }; 216 | 217 | this.updateRotationVector = function() { 218 | 219 | this.rotationVector.x = ( -this.moveState.pitchDown + this.moveState.pitchUp ); 220 | this.rotationVector.y = ( -this.moveState.yawRight + this.moveState.yawLeft ); 221 | this.rotationVector.z = ( -this.moveState.rollRight + this.moveState.rollLeft ); 222 | 223 | //console.log( 'rotate:', [ this.rotationVector.x, this.rotationVector.y, this.rotationVector.z ] ); 224 | 225 | }; 226 | 227 | this.getContainerDimensions = function() { 228 | 229 | if ( this.domElement != document ) { 230 | 231 | return { 232 | size : [ this.domElement.offsetWidth, this.domElement.offsetHeight ], 233 | offset : [ this.domElement.offsetLeft, this.domElement.offsetTop ] 234 | }; 235 | 236 | } else { 237 | 238 | return { 239 | size : [ window.innerWidth, window.innerHeight ], 240 | offset : [ 0, 0 ] 241 | }; 242 | 243 | } 244 | 245 | }; 246 | 247 | function bind( scope, fn ) { 248 | 249 | return function () { 250 | 251 | fn.apply( scope, arguments ); 252 | 253 | }; 254 | 255 | }; 256 | 257 | this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false ); 258 | 259 | this.domElement.addEventListener( 'mousemove', bind( this, this.mousemove ), false ); 260 | this.domElement.addEventListener( 'mousedown', bind( this, this.mousedown ), false ); 261 | this.domElement.addEventListener( 'mouseup', bind( this, this.mouseup ), false ); 262 | 263 | this.domElement.addEventListener( 'keydown', bind( this, this.keydown ), false ); 264 | this.domElement.addEventListener( 'keyup', bind( this, this.keyup ), false ); 265 | 266 | this.updateMovementVector(); 267 | this.updateRotationVector(); 268 | 269 | }; 270 | -------------------------------------------------------------------------------- /libs/GeometryExporter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | */ 4 | 5 | THREE.GeometryExporter = function () {}; 6 | 7 | THREE.GeometryExporter.prototype = { 8 | 9 | constructor: THREE.GeometryExporter, 10 | 11 | parse: function ( geometry ) { 12 | 13 | var output = { 14 | metadata: { 15 | version: 4.0, 16 | type: 'geometry', 17 | generator: 'GeometryExporter' 18 | } 19 | }; 20 | 21 | var vertices = []; 22 | 23 | for ( var i = 0; i < geometry.vertices.length; i ++ ) { 24 | 25 | var vertex = geometry.vertices[ i ]; 26 | vertices.push( vertex.x, vertex.y, vertex.z ); 27 | 28 | } 29 | 30 | var faces = []; 31 | var normals = []; 32 | var normalsHash = {}; 33 | var colors = []; 34 | var colorsHash = {}; 35 | var uvs = []; 36 | var uvsHash = {}; 37 | 38 | for ( var i = 0; i < geometry.faces.length; i ++ ) { 39 | 40 | var face = geometry.faces[ i ]; 41 | 42 | var isTriangle = face instanceof THREE.Face3; 43 | var hasMaterial = false; // face.materialIndex !== undefined; 44 | var hasFaceUv = false; // deprecated 45 | var hasFaceVertexUv = geometry.faceVertexUvs[ 0 ].length > 0; 46 | var hasFaceNormal = face.normal.length() > 0; 47 | var hasFaceVertexNormal = face.vertexNormals.length > 0; 48 | var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1; 49 | var hasFaceVertexColor = face.vertexColors.length > 0; 50 | 51 | var faceType = 0; 52 | 53 | faceType = setBit( faceType, 0, ! isTriangle ); 54 | faceType = setBit( faceType, 1, hasMaterial ); 55 | faceType = setBit( faceType, 2, hasFaceUv ); 56 | faceType = setBit( faceType, 3, hasFaceVertexUv ); 57 | faceType = setBit( faceType, 4, hasFaceNormal ); 58 | faceType = setBit( faceType, 5, hasFaceVertexNormal ); 59 | faceType = setBit( faceType, 6, hasFaceColor ); 60 | faceType = setBit( faceType, 7, hasFaceVertexColor ); 61 | 62 | faces.push( faceType ); 63 | 64 | if ( isTriangle ) { 65 | 66 | faces.push( face.a, face.b, face.c ); 67 | 68 | } else { 69 | 70 | faces.push( face.a, face.b, face.c, face.d ); 71 | 72 | } 73 | 74 | /* 75 | if ( hasMaterial ) { 76 | 77 | faces.push( face.materialIndex ); 78 | 79 | } 80 | */ 81 | 82 | if ( hasFaceVertexUv ) { 83 | 84 | var faceVertexUvs = geometry.faceVertexUvs[ 0 ][ i ]; 85 | 86 | if ( isTriangle ) { 87 | 88 | faces.push( 89 | getUvIndex( faceVertexUvs[ 0 ] ), 90 | getUvIndex( faceVertexUvs[ 1 ] ), 91 | getUvIndex( faceVertexUvs[ 2 ] ) 92 | ); 93 | 94 | } else { 95 | 96 | faces.push( 97 | getUvIndex( faceVertexUvs[ 0 ] ), 98 | getUvIndex( faceVertexUvs[ 1 ] ), 99 | getUvIndex( faceVertexUvs[ 2 ] ), 100 | getUvIndex( faceVertexUvs[ 3 ] ) 101 | ); 102 | 103 | } 104 | 105 | } 106 | 107 | if ( hasFaceNormal ) { 108 | 109 | faces.push( getNormalIndex( face.normal ) ); 110 | 111 | } 112 | 113 | if ( hasFaceVertexNormal ) { 114 | 115 | var vertexNormals = face.vertexNormals; 116 | 117 | if ( isTriangle ) { 118 | 119 | faces.push( 120 | getNormalIndex( vertexNormals[ 0 ] ), 121 | getNormalIndex( vertexNormals[ 1 ] ), 122 | getNormalIndex( vertexNormals[ 2 ] ) 123 | ); 124 | 125 | } else { 126 | 127 | faces.push( 128 | getNormalIndex( vertexNormals[ 0 ] ), 129 | getNormalIndex( vertexNormals[ 1 ] ), 130 | getNormalIndex( vertexNormals[ 2 ] ), 131 | getNormalIndex( vertexNormals[ 3 ] ) 132 | ); 133 | 134 | } 135 | 136 | } 137 | 138 | if ( hasFaceColor ) { 139 | 140 | faces.push( getColorIndex( face.color ) ); 141 | 142 | } 143 | 144 | if ( hasFaceVertexColor ) { 145 | 146 | var vertexColors = face.vertexColors; 147 | 148 | if ( isTriangle ) { 149 | 150 | faces.push( 151 | getColorIndex( vertexColors[ 0 ] ), 152 | getColorIndex( vertexColors[ 1 ] ), 153 | getColorIndex( vertexColors[ 2 ] ) 154 | ); 155 | 156 | } else { 157 | 158 | faces.push( 159 | getColorIndex( vertexColors[ 0 ] ), 160 | getColorIndex( vertexColors[ 1 ] ), 161 | getColorIndex( vertexColors[ 2 ] ), 162 | getColorIndex( vertexColors[ 3 ] ) 163 | ); 164 | 165 | } 166 | 167 | } 168 | 169 | } 170 | 171 | function setBit( value, position, enabled ) { 172 | 173 | return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position) ); 174 | 175 | } 176 | 177 | function getNormalIndex( normal ) { 178 | 179 | var hash = normal.x.toString() + normal.y.toString() + normal.z.toString(); 180 | 181 | if ( normalsHash[ hash ] !== undefined ) { 182 | 183 | return normalsHash[ hash ]; 184 | 185 | } 186 | 187 | normalsHash[ hash ] = normals.length / 3; 188 | normals.push( normal.x, normal.y, normal.z ); 189 | 190 | return normalsHash[ hash ]; 191 | 192 | } 193 | 194 | function getColorIndex( color ) { 195 | 196 | var hash = color.r.toString() + color.g.toString() + color.b.toString(); 197 | 198 | if ( colorsHash[ hash ] !== undefined ) { 199 | 200 | return colorsHash[ hash ]; 201 | 202 | } 203 | 204 | colorsHash[ hash ] = colors.length; 205 | colors.push( color.getHex() ); 206 | 207 | return colorsHash[ hash ]; 208 | 209 | } 210 | 211 | function getUvIndex( uv ) { 212 | 213 | var hash = uv.x.toString() + uv.y.toString(); 214 | 215 | if ( uvsHash[ hash ] !== undefined ) { 216 | 217 | return uvsHash[ hash ]; 218 | 219 | } 220 | 221 | uvsHash[ hash ] = uvs.length / 2; 222 | uvs.push( uv.x, uv.y ); 223 | 224 | return uvsHash[ hash ]; 225 | 226 | } 227 | 228 | output.vertices = vertices; 229 | output.normals = normals; 230 | if ( colors.length > 0 ) output.colors = colors; 231 | if ( uvs.length > 0 ) output.uvs = [ uvs ]; // temporal backward compatibility 232 | output.faces = faces; 233 | 234 | // 235 | 236 | return output; 237 | 238 | } 239 | 240 | }; 241 | -------------------------------------------------------------------------------- /libs/MD2Character.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.MD2Character = function () { 6 | 7 | var scope = this; 8 | 9 | this.scale = 1; 10 | this.animationFPS = 6; 11 | 12 | this.root = new THREE.Object3D(); 13 | 14 | this.meshBody = null; 15 | this.meshWeapon = null; 16 | 17 | this.skinsBody = []; 18 | this.skinsWeapon = []; 19 | 20 | this.weapons = []; 21 | 22 | this.activeAnimation = null; 23 | 24 | this.onLoadComplete = function () {}; 25 | 26 | this.loadCounter = 0; 27 | 28 | this.loadParts = function ( config ) { 29 | 30 | this.loadCounter = config.weapons.length * 2 + config.skins.length + 1; 31 | 32 | var weaponsTextures = [] 33 | for ( var i = 0; i < config.weapons.length; i ++ ) weaponsTextures[ i ] = config.weapons[ i ][ 1 ]; 34 | 35 | // SKINS 36 | 37 | this.skinsBody = loadTextures( config.baseUrl + "skins/", config.skins ); 38 | this.skinsWeapon = loadTextures( config.baseUrl + "skins/", weaponsTextures ); 39 | 40 | // BODY 41 | 42 | var loader = new THREE.JSONLoader(); 43 | 44 | loader.load( config.baseUrl + config.body, function( geo ) { 45 | 46 | geo.computeBoundingBox(); 47 | scope.root.position.y = - scope.scale * geo.boundingBox.min.y; 48 | 49 | var mesh = createPart( geo, scope.skinsBody[ 0 ] ); 50 | mesh.scale.set( scope.scale, scope.scale, scope.scale ); 51 | 52 | scope.root.add( mesh ); 53 | 54 | scope.meshBody = mesh; 55 | scope.activeAnimation = geo.firstAnimation; 56 | 57 | checkLoadingComplete(); 58 | 59 | } ); 60 | 61 | // WEAPONS 62 | 63 | var generateCallback = function ( index, name ) { 64 | 65 | return function( geo ) { 66 | 67 | var mesh = createPart( geo, scope.skinsWeapon[ index ] ); 68 | mesh.scale.set( scope.scale, scope.scale, scope.scale ); 69 | mesh.visible = false; 70 | 71 | mesh.name = name; 72 | 73 | scope.root.add( mesh ); 74 | 75 | scope.weapons[ index ] = mesh; 76 | scope.meshWeapon = mesh; 77 | 78 | checkLoadingComplete(); 79 | 80 | } 81 | 82 | } 83 | 84 | for ( var i = 0; i < config.weapons.length; i ++ ) { 85 | 86 | loader.load( config.baseUrl + config.weapons[ i ][ 0 ], generateCallback( i, config.weapons[ i ][ 0 ] ) ); 87 | 88 | } 89 | 90 | }; 91 | 92 | this.setPlaybackRate = function ( rate ) { 93 | 94 | if ( this.meshBody ) this.meshBody.duration = this.meshBody.baseDuration / rate; 95 | if ( this.meshWeapon ) this.meshWeapon.duration = this.meshWeapon.baseDuration / rate; 96 | 97 | }; 98 | 99 | this.setWireframe = function ( wireframeEnabled ) { 100 | 101 | if ( wireframeEnabled ) { 102 | 103 | if ( this.meshBody ) this.meshBody.material = this.meshBody.materialWireframe; 104 | if ( this.meshWeapon ) this.meshWeapon.material = this.meshWeapon.materialWireframe; 105 | 106 | } else { 107 | 108 | if ( this.meshBody ) this.meshBody.material = this.meshBody.materialTexture; 109 | if ( this.meshWeapon ) this.meshWeapon.material = this.meshWeapon.materialTexture; 110 | 111 | } 112 | 113 | }; 114 | 115 | this.setSkin = function( index ) { 116 | 117 | if ( this.meshBody && this.meshBody.material.wireframe === false ) { 118 | 119 | this.meshBody.material.map = this.skinsBody[ index ]; 120 | 121 | } 122 | 123 | }; 124 | 125 | this.setWeapon = function ( index ) { 126 | 127 | for ( var i = 0; i < this.weapons.length; i ++ ) this.weapons[ i ].visible = false; 128 | 129 | var activeWeapon = this.weapons[ index ]; 130 | 131 | if ( activeWeapon ) { 132 | 133 | activeWeapon.visible = true; 134 | this.meshWeapon = activeWeapon; 135 | 136 | activeWeapon.playAnimation( this.activeAnimation, this.animationFPS ); 137 | 138 | this.meshWeapon.baseDuration = this.meshWeapon.duration; 139 | 140 | this.meshWeapon.time = this.meshBody.time; 141 | this.meshWeapon.duration = this.meshBody.duration; 142 | 143 | } 144 | 145 | }; 146 | 147 | this.setAnimation = function ( animationName ) { 148 | 149 | if ( this.meshBody ) { 150 | 151 | this.meshBody.playAnimation( animationName, this.animationFPS ); 152 | this.meshBody.baseDuration = this.meshBody.duration; 153 | 154 | } 155 | 156 | if ( this.meshWeapon ) { 157 | 158 | this.meshWeapon.playAnimation( animationName, this.animationFPS ); 159 | this.meshWeapon.baseDuration = this.meshWeapon.duration; 160 | this.meshWeapon.time = this.meshBody.time; 161 | 162 | } 163 | 164 | this.activeAnimation = animationName; 165 | 166 | }; 167 | 168 | this.update = function ( delta ) { 169 | 170 | if ( this.meshBody ) { 171 | 172 | this.meshBody.updateAnimation( 1000 * delta ); 173 | 174 | } 175 | 176 | if ( this.meshWeapon ) { 177 | 178 | this.meshWeapon.updateAnimation( 1000 * delta ); 179 | 180 | } 181 | 182 | }; 183 | 184 | function loadTextures( baseUrl, textureUrls ) { 185 | 186 | var mapping = new THREE.UVMapping(); 187 | var textures = []; 188 | 189 | for ( var i = 0; i < textureUrls.length; i ++ ) { 190 | 191 | textures[ i ] = THREE.ImageUtils.loadTexture( baseUrl + textureUrls[ i ], mapping, checkLoadingComplete ); 192 | textures[ i ].name = textureUrls[ i ]; 193 | 194 | } 195 | 196 | return textures; 197 | 198 | }; 199 | 200 | function createPart( geometry, skinMap ) { 201 | 202 | geometry.computeMorphNormals(); 203 | 204 | var whiteMap = THREE.ImageUtils.generateDataTexture( 1, 1, new THREE.Color( 0xffffff ) ); 205 | var materialWireframe = new THREE.MeshPhongMaterial( { color: 0xffaa00, specular: 0x111111, shininess: 50, wireframe: true, shading: THREE.SmoothShading, map: whiteMap, morphTargets: true, morphNormals: true, metal: false } ); 206 | 207 | var materialTexture = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x111111, shininess: 50, wireframe: false, shading: THREE.SmoothShading, map: skinMap, morphTargets: true, morphNormals: true, metal: false } ); 208 | materialTexture.wrapAround = true; 209 | 210 | // 211 | 212 | var mesh = new THREE.MorphAnimMesh( geometry, materialTexture ); 213 | mesh.rotation.y = -Math.PI/2; 214 | 215 | mesh.castShadow = true; 216 | mesh.receiveShadow = true; 217 | 218 | // 219 | 220 | mesh.materialTexture = materialTexture; 221 | mesh.materialWireframe = materialWireframe; 222 | 223 | // 224 | 225 | mesh.parseAnimations(); 226 | 227 | mesh.playAnimation( geometry.firstAnimation, scope.animationFPS ); 228 | mesh.baseDuration = mesh.duration; 229 | 230 | return mesh; 231 | 232 | }; 233 | 234 | function checkLoadingComplete() { 235 | 236 | scope.loadCounter -= 1; 237 | 238 | if ( scope.loadCounter === 0 ) scope.onLoadComplete(); 239 | 240 | }; 241 | 242 | }; 243 | -------------------------------------------------------------------------------- /libs/MaskPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.MaskPass = function ( scene, camera ) { 6 | 7 | this.scene = scene; 8 | this.camera = camera; 9 | 10 | this.enabled = true; 11 | this.clear = true; 12 | this.needsSwap = false; 13 | 14 | this.inverse = false; 15 | 16 | }; 17 | 18 | THREE.MaskPass.prototype = { 19 | 20 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 21 | 22 | var context = renderer.context; 23 | 24 | // don't update color or depth 25 | 26 | context.colorMask( false, false, false, false ); 27 | context.depthMask( false ); 28 | 29 | // set up stencil 30 | 31 | var writeValue, clearValue; 32 | 33 | if ( this.inverse ) { 34 | 35 | writeValue = 0; 36 | clearValue = 1; 37 | 38 | } else { 39 | 40 | writeValue = 1; 41 | clearValue = 0; 42 | 43 | } 44 | 45 | context.enable( context.STENCIL_TEST ); 46 | context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE ); 47 | context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff ); 48 | context.clearStencil( clearValue ); 49 | 50 | // draw into the stencil buffer 51 | 52 | renderer.render( this.scene, this.camera, readBuffer, this.clear ); 53 | renderer.render( this.scene, this.camera, writeBuffer, this.clear ); 54 | 55 | // re-enable update of color and depth 56 | 57 | context.colorMask( true, true, true, true ); 58 | context.depthMask( true ); 59 | 60 | // only render where stencil is set to 1 61 | 62 | context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1 63 | context.stencilOp( context.KEEP, context.KEEP, context.KEEP ); 64 | 65 | } 66 | 67 | }; 68 | 69 | 70 | THREE.ClearMaskPass = function () { 71 | 72 | this.enabled = true; 73 | 74 | }; 75 | 76 | THREE.ClearMaskPass.prototype = { 77 | 78 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 79 | 80 | var context = renderer.context; 81 | 82 | context.disable( context.STENCIL_TEST ); 83 | 84 | } 85 | 86 | }; 87 | -------------------------------------------------------------------------------- /libs/PLYLoader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Wei Meng / http://about.me/menway 3 | * 4 | * Description: A THREE loader for PLY ASCII files (known as the Polygon File Format or the Stanford Triangle Format). 5 | * 6 | * Currently only supports ASCII encoded files. 7 | * 8 | * Limitations: ASCII decoding assumes file is UTF-8. 9 | * 10 | * Usage: 11 | * var loader = new THREE.PLYLoader(); 12 | * loader.addEventListener( 'load', function ( event ) { 13 | * 14 | * var geometry = event.content; 15 | * scene.add( new THREE.Mesh( geometry ) ); 16 | * 17 | * } ); 18 | * loader.load( './models/ply/ascii/dolphins.ply' ); 19 | */ 20 | 21 | 22 | THREE.PLYLoader = function () {}; 23 | 24 | THREE.PLYLoader.prototype = { 25 | 26 | constructor: THREE.PLYLoader, 27 | 28 | addEventListener: THREE.EventDispatcher.prototype.addEventListener, 29 | hasEventListener: THREE.EventDispatcher.prototype.hasEventListener, 30 | removeEventListener: THREE.EventDispatcher.prototype.removeEventListener, 31 | dispatchEvent: THREE.EventDispatcher.prototype.dispatchEvent, 32 | 33 | load: function ( url, callback ) { 34 | 35 | var scope = this; 36 | var request = new XMLHttpRequest(); 37 | 38 | request.addEventListener( 'load', function ( event ) { 39 | 40 | var geometry = scope.parse( event.target.response ); 41 | 42 | scope.dispatchEvent( { type: 'load', content: geometry } ); 43 | 44 | if ( callback ) callback( geometry ); 45 | 46 | }, false ); 47 | 48 | request.addEventListener( 'progress', function ( event ) { 49 | 50 | scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } ); 51 | 52 | }, false ); 53 | 54 | request.addEventListener( 'error', function () { 55 | 56 | scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } ); 57 | 58 | }, false ); 59 | 60 | request.open( 'GET', url, true ); 61 | request.responseType = "arraybuffer"; 62 | request.send( null ); 63 | 64 | }, 65 | 66 | bin2str: function (buf) { 67 | 68 | var array_buffer = new Uint8Array(buf); 69 | var str = ''; 70 | for(var i = 0; i < buf.byteLength; i++) { 71 | str += String.fromCharCode(array_buffer[i]); // implicitly assumes little-endian 72 | } 73 | 74 | return str; 75 | 76 | }, 77 | 78 | isASCII: function(buf){ 79 | 80 | // currently only supports ASCII encoded files. 81 | return true; 82 | 83 | }, 84 | 85 | parse: function ( data ) { 86 | 87 | if ( data instanceof ArrayBuffer ) { 88 | 89 | return this.isASCII( data ) 90 | ? this.parseASCII( this.bin2str( data ) ) 91 | : this.parseBinary( data ); 92 | 93 | } else { 94 | 95 | return this.parseASCII( data ); 96 | 97 | } 98 | 99 | }, 100 | 101 | parseASCII: function ( data ) { 102 | 103 | // PLY ascii format specification, as per http://en.wikipedia.org/wiki/PLY_(file_format) 104 | 105 | var geometry = new THREE.Geometry(); 106 | 107 | var result; 108 | 109 | var patternHeader = /ply([\s\S]*)end_header/; 110 | var header = ""; 111 | if ( ( result = patternHeader.exec( data ) ) != null ) { 112 | header = result [ 1 ]; 113 | } 114 | 115 | var patternBody = /end_header([\s\S]*)$/; 116 | var body = ""; 117 | if ( ( result = patternBody.exec( data ) ) != null ) { 118 | body = result [ 1 ]; 119 | } 120 | 121 | var patternVertexCount = /element[\s]+vertex[\s]+(\d+)/g; 122 | var vertexCount = 0; 123 | if ( ( result = patternVertexCount.exec( header ) ) != null ) { 124 | vertexCount = parseInt( result[ 1 ] ); 125 | } 126 | 127 | var patternFaceCount = /element[\s]+face[\s]+(\d+)/g; 128 | var faceCount = 0; 129 | if ( ( result = patternFaceCount.exec( header ) ) != null ) { 130 | faceCount = parseInt( result[ 1 ] ); 131 | } 132 | 133 | if ( vertexCount != 0 && faceCount != 0 ) { 134 | // Vertex 135 | // assume x y z 136 | var patternVertex = /([-+]?[0-9]+\.?[0-9]*([eE][-+]?[0-9]+)?)+[\s]+([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)+[\s]+([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)+/g; 137 | for ( var i = 0; i < vertexCount; i++) { 138 | if ( ( result = patternVertex.exec( body ) ) != null ) { 139 | geometry.vertices.push( new THREE.Vector3( parseFloat( result[ 1 ] ), parseFloat( result[ 3 ] ), parseFloat( result[ 5 ] ) ) ); 140 | } else { 141 | console.error('Vertex error: vertex count mismatch.'); 142 | return geometry; 143 | } 144 | } 145 | 146 | // Face 147 | // assume 3 index0 index1 index2 148 | var patternFace = /3[\s]+([-+]?[0-9]+)[\s]+([-+]?[0-9]+)[\s]+([-+]?[0-9]+)/g; 149 | for (var i = 0; i < faceCount; i++) { 150 | if ( ( result = patternFace.exec( body ) ) != null ) { 151 | geometry.faces.push( new THREE.Face3( parseInt( result[ 1 ] ), parseInt( result[ 2 ] ), parseInt( result[ 3 ] ) ) ); 152 | } else { 153 | console.error('Face error: vertex count mismatch.'); 154 | return geometry; 155 | } 156 | } 157 | 158 | } else { 159 | console.error( 'Header error: vertexCount(' + vertexCount + '), faceCount(' + faceCount + ').' ); 160 | } 161 | 162 | geometry.computeCentroids(); 163 | geometry.computeBoundingSphere(); 164 | 165 | return geometry; 166 | 167 | }, 168 | 169 | parseBinary: function (buf) { 170 | 171 | // not supported yet 172 | console.error('Not supported yet.'); 173 | 174 | } 175 | 176 | 177 | }; -------------------------------------------------------------------------------- /libs/ParametricGeometries.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author zz85 3 | * 4 | * Experimenting of primitive geometry creation using Surface Parametric equations 5 | * 6 | */ 7 | 8 | 9 | THREE.ParametricGeometries = { 10 | 11 | klein: function (v, u) { 12 | u *= Math.PI; 13 | v *= 2 * Math.PI; 14 | 15 | u = u * 2; 16 | var x, y, z; 17 | if (u < Math.PI) { 18 | x = 3 * Math.cos(u) * (1 + Math.sin(u)) + (2 * (1 - Math.cos(u) / 2)) * Math.cos(u) * Math.cos(v); 19 | z = -8 * Math.sin(u) - 2 * (1 - Math.cos(u) / 2) * Math.sin(u) * Math.cos(v); 20 | } else { 21 | x = 3 * Math.cos(u) * (1 + Math.sin(u)) + (2 * (1 - Math.cos(u) / 2)) * Math.cos(v + Math.PI); 22 | z = -8 * Math.sin(u); 23 | } 24 | 25 | y = -2 * (1 - Math.cos(u) / 2) * Math.sin(v); 26 | 27 | return new THREE.Vector3(x, y, z); 28 | }, 29 | 30 | plane: function (width, height) { 31 | 32 | return function(u, v) { 33 | var x = u * width; 34 | var y = 0; 35 | var z = v * height; 36 | 37 | return new THREE.Vector3(x, y, z); 38 | }; 39 | }, 40 | 41 | mobius: function(u, t) { 42 | 43 | // flat mobius strip 44 | // http://www.wolframalpha.com/input/?i=M%C3%B6bius+strip+parametric+equations&lk=1&a=ClashPrefs_*Surface.MoebiusStrip.SurfaceProperty.ParametricEquations- 45 | u = u - 0.5; 46 | var v = 2 * Math.PI * t; 47 | 48 | var x, y, z; 49 | 50 | var a = 2; 51 | x = Math.cos(v) * (a + u * Math.cos(v/2)); 52 | y = Math.sin(v) * (a + u * Math.cos(v/2)); 53 | z = u * Math.sin(v/2); 54 | return new THREE.Vector3(x, y, z); 55 | 56 | }, 57 | 58 | mobius3d: function(u, t) { 59 | 60 | // volumetric mobius strip 61 | u *= Math.PI; 62 | t *= 2 * Math.PI; 63 | 64 | u = u * 2; 65 | var phi = u / 2; 66 | var major = 2.25, a = 0.125, b = 0.65; 67 | var x, y, z; 68 | x = a * Math.cos(t) * Math.cos(phi) - b * Math.sin(t) * Math.sin(phi); 69 | z = a * Math.cos(t) * Math.sin(phi) + b * Math.sin(t) * Math.cos(phi); 70 | y = (major + x) * Math.sin(u); 71 | x = (major + x) * Math.cos(u); 72 | return new THREE.Vector3(x, y, z); 73 | } 74 | 75 | }; 76 | 77 | 78 | /********************************************* 79 | * 80 | * Parametric Replacement for TubeGeometry 81 | * 82 | *********************************************/ 83 | 84 | THREE.ParametricGeometries.TubeGeometry = function(path, segments, radius, segmentsRadius, closed, debug) { 85 | 86 | this.path = path; 87 | this.segments = segments || 64; 88 | this.radius = radius || 1; 89 | this.segmentsRadius = segmentsRadius || 8; 90 | this.closed = closed || false; 91 | if (debug) this.debug = new THREE.Object3D(); 92 | 93 | 94 | var scope = this, 95 | 96 | tangent, normal, binormal, 97 | 98 | numpoints = this.segments + 1, 99 | 100 | x, y, z, tx, ty, tz, u, v, 101 | 102 | cx, cy, pos, pos2 = new THREE.Vector3(), 103 | i, j, ip, jp, a, b, c, d, uva, uvb, uvc, uvd; 104 | 105 | var frames = new THREE.TubeGeometry.FrenetFrames(path, segments, closed), 106 | tangents = frames.tangents, 107 | normals = frames.normals, 108 | binormals = frames.binormals; 109 | 110 | // proxy internals 111 | this.tangents = tangents; 112 | this.normals = normals; 113 | this.binormals = binormals; 114 | 115 | 116 | 117 | var ParametricTube = function(u, v) { 118 | v *= 2 * Math.PI; 119 | 120 | i = u * (numpoints - 1); 121 | i = Math.floor(i); 122 | 123 | pos = path.getPointAt(u); 124 | 125 | tangent = tangents[i]; 126 | normal = normals[i]; 127 | binormal = binormals[i]; 128 | 129 | if (scope.debug) { 130 | 131 | scope.debug.add(new THREE.ArrowHelper(tangent, pos, radius, 0x0000ff)); 132 | scope.debug.add(new THREE.ArrowHelper(normal, pos, radius, 0xff0000)); 133 | scope.debug.add(new THREE.ArrowHelper(binormal, pos, radius, 0x00ff00)); 134 | 135 | } 136 | 137 | cx = -scope.radius * Math.cos(v); // TODO: Hack: Negating it so it faces outside. 138 | cy = scope.radius * Math.sin(v); 139 | 140 | pos2.copy(pos); 141 | pos2.x += cx * normal.x + cy * binormal.x; 142 | pos2.y += cx * normal.y + cy * binormal.y; 143 | pos2.z += cx * normal.z + cy * binormal.z; 144 | 145 | return pos2.clone(); 146 | }; 147 | 148 | THREE.ParametricGeometry.call(this, ParametricTube, segments, segmentsRadius); 149 | 150 | }; 151 | 152 | THREE.ParametricGeometries.TubeGeometry.prototype = Object.create( THREE.Geometry.prototype ); 153 | 154 | 155 | /********************************************* 156 | * 157 | * Parametric Replacement for TorusKnotGeometry 158 | * 159 | *********************************************/ 160 | THREE.ParametricGeometries.TorusKnotGeometry = function ( radius, tube, segmentsR, segmentsT, p, q, heightScale ) { 161 | 162 | var scope = this; 163 | 164 | this.radius = radius || 200; 165 | this.tube = tube || 40; 166 | this.segmentsR = segmentsR || 64; 167 | this.segmentsT = segmentsT || 8; 168 | this.p = p || 2; 169 | this.q = q || 3; 170 | this.heightScale = heightScale || 1; 171 | 172 | 173 | var TorusKnotCurve = THREE.Curve.create( 174 | 175 | function() { 176 | }, 177 | 178 | function(t) { 179 | 180 | t *= Math.PI * 2; 181 | 182 | var r = 0.5; 183 | 184 | var tx = (1 + r * Math.cos(q * t)) * Math.cos(p * t), 185 | ty = (1 + r * Math.cos(q * t)) * Math.sin(p * t), 186 | tz = r * Math.sin(q * t); 187 | 188 | return new THREE.Vector3(tx, ty * heightScale, tz).multiplyScalar(radius); 189 | 190 | } 191 | 192 | ); 193 | var segments = segmentsR; 194 | var radiusSegments = segmentsT; 195 | var extrudePath = new TorusKnotCurve(); 196 | 197 | THREE.ParametricGeometries.TubeGeometry.call( this, extrudePath, segments, tube, radiusSegments, true, false ); 198 | 199 | 200 | }; 201 | 202 | THREE.ParametricGeometries.TorusKnotGeometry.prototype = Object.create( THREE.Geometry.prototype ); 203 | 204 | 205 | /********************************************* 206 | * 207 | * Parametric Replacement for SphereGeometry 208 | * 209 | *********************************************/ 210 | THREE.ParametricGeometries.SphereGeometry = function(size, u, v) { 211 | 212 | function sphere(u, v) { 213 | u *= Math.PI; 214 | v *= 2 * Math.PI; 215 | 216 | var x = size * Math.sin(u) * Math.cos(v); 217 | var y = size * Math.sin(u) * Math.sin(v); 218 | var z = size * Math.cos(u); 219 | 220 | 221 | return new THREE.Vector3(x, y, z); 222 | } 223 | 224 | THREE.ParametricGeometry.call(this, sphere, u, v, !true); 225 | 226 | }; 227 | 228 | THREE.ParametricGeometries.SphereGeometry.prototype = Object.create( THREE.Geometry.prototype ); 229 | 230 | 231 | /********************************************* 232 | * 233 | * Parametric Replacement for PlaneGeometry 234 | * 235 | *********************************************/ 236 | 237 | THREE.ParametricGeometries.PlaneGeometry = function(width, depth, segmentsWidth, segmentsDepth) { 238 | 239 | function plane(u, v) { 240 | 241 | var x = u * width; 242 | var y = 0; 243 | var z = v * depth; 244 | 245 | return new THREE.Vector3(x, y, z); 246 | } 247 | 248 | THREE.ParametricGeometry.call(this, plane, segmentsWidth, segmentsDepth); 249 | 250 | }; 251 | 252 | THREE.ParametricGeometries.PlaneGeometry.prototype = Object.create( THREE.Geometry.prototype ); -------------------------------------------------------------------------------- /libs/RenderPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.RenderPass = function ( scene, camera, overrideMaterial, clearColor, clearAlpha ) { 6 | 7 | this.scene = scene; 8 | this.camera = camera; 9 | 10 | this.overrideMaterial = overrideMaterial; 11 | 12 | this.clearColor = clearColor; 13 | this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1; 14 | 15 | this.oldClearColor = new THREE.Color(); 16 | this.oldClearAlpha = 1; 17 | 18 | this.enabled = true; 19 | this.clear = true; 20 | this.needsSwap = false; 21 | 22 | }; 23 | 24 | THREE.RenderPass.prototype = { 25 | 26 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 27 | 28 | this.scene.overrideMaterial = this.overrideMaterial; 29 | 30 | if ( this.clearColor ) { 31 | 32 | this.oldClearColor.copy( renderer.getClearColor() ); 33 | this.oldClearAlpha = renderer.getClearAlpha(); 34 | 35 | renderer.setClearColor( this.clearColor, this.clearAlpha ); 36 | 37 | } 38 | 39 | renderer.render( this.scene, this.camera, readBuffer, this.clear ); 40 | 41 | if ( this.clearColor ) { 42 | 43 | renderer.setClearColor( this.oldClearColor, this.oldClearAlpha ); 44 | 45 | } 46 | 47 | this.scene.overrideMaterial = null; 48 | 49 | } 50 | 51 | }; 52 | -------------------------------------------------------------------------------- /libs/RollControls.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mikael emtinger / http://gomo.se/ 3 | * @author alteredq / http://alteredqualia.com/ 4 | * 5 | * Eye is fixed in position, camera's up is fixed to +Y, direction is constantly 6 | * updated, with direction of mouse on screen compared to screen's center determining 7 | * the direction of drift. 8 | */ 9 | 10 | THREE.RollControls = function ( object, domElement ) { 11 | 12 | this.object = object; 13 | this.domElement = ( domElement !== undefined ) ? domElement : document; 14 | 15 | // API 16 | 17 | this.mouseLook = true; 18 | this.autoForward = false; 19 | 20 | this.lookSpeed = 1; 21 | this.movementSpeed = 1; 22 | this.rollSpeed = 1; 23 | 24 | this.constrainVertical = [ -0.9, 0.9 ]; 25 | 26 | // disable default target object behavior 27 | 28 | this.object.matrixAutoUpdate = false; 29 | 30 | // internals 31 | 32 | this.forward = new THREE.Vector3( 0, 0, 1 ); 33 | this.roll = 0; 34 | 35 | var xTemp = new THREE.Vector3(); 36 | var yTemp = new THREE.Vector3(); 37 | var zTemp = new THREE.Vector3(); 38 | var rollMatrix = new THREE.Matrix4(); 39 | 40 | var doRoll = false, rollDirection = 1, forwardSpeed = 0, sideSpeed = 0, upSpeed = 0; 41 | 42 | var mouseX = 0, mouseY = 0; 43 | 44 | var windowHalfX = 0; 45 | var windowHalfY = 0; 46 | 47 | // 48 | 49 | this.handleResize = function () { 50 | 51 | windowHalfX = window.innerWidth / 2; 52 | windowHalfY = window.innerHeight / 2; 53 | 54 | }; 55 | 56 | // custom update 57 | 58 | this.update = function ( delta ) { 59 | 60 | if ( this.mouseLook ) { 61 | 62 | var actualLookSpeed = delta * this.lookSpeed; 63 | 64 | this.rotateHorizontally( actualLookSpeed * mouseX ); 65 | this.rotateVertically( actualLookSpeed * mouseY ); 66 | 67 | } 68 | 69 | var actualSpeed = delta * this.movementSpeed; 70 | var forwardOrAuto = ( forwardSpeed > 0 || ( this.autoForward && ! ( forwardSpeed < 0 ) ) ) ? 1 : forwardSpeed; 71 | 72 | this.object.translateZ( -actualSpeed * forwardOrAuto ); 73 | this.object.translateX( actualSpeed * sideSpeed ); 74 | this.object.translateY( actualSpeed * upSpeed ); 75 | 76 | if( doRoll ) { 77 | 78 | this.roll += this.rollSpeed * delta * rollDirection; 79 | 80 | } 81 | 82 | // cap forward up / down 83 | 84 | if( this.forward.y > this.constrainVertical[ 1 ] ) { 85 | 86 | this.forward.y = this.constrainVertical[ 1 ]; 87 | this.forward.normalize(); 88 | 89 | } else if( this.forward.y < this.constrainVertical[ 0 ] ) { 90 | 91 | this.forward.y = this.constrainVertical[ 0 ]; 92 | this.forward.normalize(); 93 | 94 | } 95 | 96 | 97 | // construct unrolled camera matrix 98 | 99 | zTemp.copy( this.forward ); 100 | yTemp.set( 0, 1, 0 ); 101 | 102 | xTemp.crossVectors( yTemp, zTemp ).normalize(); 103 | yTemp.crossVectors( zTemp, xTemp ).normalize(); 104 | 105 | this.object.matrix.elements[0] = xTemp.x; this.object.matrix.elements[4] = yTemp.x; this.object.matrix.elements[8] = zTemp.x; 106 | this.object.matrix.elements[1] = xTemp.y; this.object.matrix.elements[5] = yTemp.y; this.object.matrix.elements[9] = zTemp.y; 107 | this.object.matrix.elements[2] = xTemp.z; this.object.matrix.elements[6] = yTemp.z; this.object.matrix.elements[10] = zTemp.z; 108 | 109 | // calculate roll matrix 110 | 111 | rollMatrix.identity(); 112 | rollMatrix.elements[0] = Math.cos( this.roll ); rollMatrix.elements[4] = -Math.sin( this.roll ); 113 | rollMatrix.elements[1] = Math.sin( this.roll ); rollMatrix.elements[5] = Math.cos( this.roll ); 114 | 115 | // multiply camera with roll 116 | 117 | this.object.matrix.multiply( rollMatrix ); 118 | this.object.matrixWorldNeedsUpdate = true; 119 | 120 | // set position 121 | 122 | this.object.matrix.elements[12] = this.object.position.x; 123 | this.object.matrix.elements[13] = this.object.position.y; 124 | this.object.matrix.elements[14] = this.object.position.z; 125 | 126 | 127 | }; 128 | 129 | this.translateX = function ( distance ) { 130 | 131 | this.object.position.x += this.object.matrix.elements[0] * distance; 132 | this.object.position.y += this.object.matrix.elements[1] * distance; 133 | this.object.position.z += this.object.matrix.elements[2] * distance; 134 | 135 | }; 136 | 137 | this.translateY = function ( distance ) { 138 | 139 | this.object.position.x += this.object.matrix.elements[4] * distance; 140 | this.object.position.y += this.object.matrix.elements[5] * distance; 141 | this.object.position.z += this.object.matrix.elements[6] * distance; 142 | 143 | }; 144 | 145 | this.translateZ = function ( distance ) { 146 | 147 | this.object.position.x -= this.object.matrix.elements[8] * distance; 148 | this.object.position.y -= this.object.matrix.elements[9] * distance; 149 | this.object.position.z -= this.object.matrix.elements[10] * distance; 150 | 151 | }; 152 | 153 | 154 | this.rotateHorizontally = function ( amount ) { 155 | 156 | // please note that the amount is NOT degrees, but a scale value 157 | 158 | xTemp.set( this.object.matrix.elements[0], this.object.matrix.elements[1], this.object.matrix.elements[2] ); 159 | xTemp.multiplyScalar( amount ); 160 | 161 | this.forward.sub( xTemp ); 162 | this.forward.normalize(); 163 | 164 | }; 165 | 166 | this.rotateVertically = function ( amount ) { 167 | 168 | // please note that the amount is NOT degrees, but a scale value 169 | 170 | yTemp.set( this.object.matrix.elements[4], this.object.matrix.elements[5], this.object.matrix.elements[6] ); 171 | yTemp.multiplyScalar( amount ); 172 | 173 | this.forward.add( yTemp ); 174 | this.forward.normalize(); 175 | 176 | }; 177 | 178 | function onKeyDown( event ) { 179 | 180 | //event.preventDefault(); 181 | 182 | switch ( event.keyCode ) { 183 | 184 | case 38: /*up*/ 185 | case 87: /*W*/ forwardSpeed = 1; break; 186 | 187 | case 37: /*left*/ 188 | case 65: /*A*/ sideSpeed = -1; break; 189 | 190 | case 40: /*down*/ 191 | case 83: /*S*/ forwardSpeed = -1; break; 192 | 193 | case 39: /*right*/ 194 | case 68: /*D*/ sideSpeed = 1; break; 195 | 196 | case 81: /*Q*/ doRoll = true; rollDirection = 1; break; 197 | case 69: /*E*/ doRoll = true; rollDirection = -1; break; 198 | 199 | case 82: /*R*/ upSpeed = 1; break; 200 | case 70: /*F*/ upSpeed = -1; break; 201 | 202 | } 203 | 204 | }; 205 | 206 | function onKeyUp( event ) { 207 | 208 | switch( event.keyCode ) { 209 | 210 | case 38: /*up*/ 211 | case 87: /*W*/ forwardSpeed = 0; break; 212 | 213 | case 37: /*left*/ 214 | case 65: /*A*/ sideSpeed = 0; break; 215 | 216 | case 40: /*down*/ 217 | case 83: /*S*/ forwardSpeed = 0; break; 218 | 219 | case 39: /*right*/ 220 | case 68: /*D*/ sideSpeed = 0; break; 221 | 222 | case 81: /*Q*/ doRoll = false; break; 223 | case 69: /*E*/ doRoll = false; break; 224 | 225 | case 82: /*R*/ upSpeed = 0; break; 226 | case 70: /*F*/ upSpeed = 0; break; 227 | 228 | } 229 | 230 | }; 231 | 232 | function onMouseMove( event ) { 233 | 234 | mouseX = ( event.clientX - windowHalfX ) / window.innerWidth; 235 | mouseY = ( event.clientY - windowHalfY ) / window.innerHeight; 236 | 237 | }; 238 | 239 | function onMouseDown ( event ) { 240 | 241 | event.preventDefault(); 242 | event.stopPropagation(); 243 | 244 | switch ( event.button ) { 245 | 246 | case 0: forwardSpeed = 1; break; 247 | case 2: forwardSpeed = -1; break; 248 | 249 | } 250 | 251 | }; 252 | 253 | function onMouseUp ( event ) { 254 | 255 | event.preventDefault(); 256 | event.stopPropagation(); 257 | 258 | switch ( event.button ) { 259 | 260 | case 0: forwardSpeed = 0; break; 261 | case 2: forwardSpeed = 0; break; 262 | 263 | } 264 | 265 | }; 266 | 267 | this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false ); 268 | 269 | this.domElement.addEventListener( 'mousemove', onMouseMove, false ); 270 | this.domElement.addEventListener( 'mousedown', onMouseDown, false ); 271 | this.domElement.addEventListener( 'mouseup', onMouseUp, false ); 272 | this.domElement.addEventListener( 'keydown', onKeyDown, false ); 273 | this.domElement.addEventListener( 'keyup', onKeyUp, false ); 274 | 275 | this.handleResize(); 276 | 277 | }; 278 | -------------------------------------------------------------------------------- /libs/ShaderPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.ShaderPass = function ( shader, textureID ) { 6 | 7 | this.textureID = ( textureID !== undefined ) ? textureID : "tDiffuse"; 8 | 9 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 10 | 11 | this.material = new THREE.ShaderMaterial( { 12 | 13 | uniforms: this.uniforms, 14 | vertexShader: shader.vertexShader, 15 | fragmentShader: shader.fragmentShader 16 | 17 | } ); 18 | 19 | this.renderToScreen = false; 20 | 21 | this.enabled = true; 22 | this.needsSwap = true; 23 | this.clear = false; 24 | 25 | }; 26 | 27 | THREE.ShaderPass.prototype = { 28 | 29 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 30 | 31 | if ( this.uniforms[ this.textureID ] ) { 32 | 33 | this.uniforms[ this.textureID ].value = readBuffer; 34 | 35 | } 36 | 37 | THREE.EffectComposer.quad.material = this.material; 38 | 39 | if ( this.renderToScreen ) { 40 | 41 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera ); 42 | 43 | } else { 44 | 45 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, writeBuffer, this.clear ); 46 | 47 | } 48 | 49 | } 50 | 51 | }; 52 | -------------------------------------------------------------------------------- /libs/VTKLoader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | */ 4 | 5 | THREE.VTKLoader = function () {}; 6 | 7 | THREE.VTKLoader.prototype = { 8 | 9 | constructor: THREE.VTKLoader, 10 | 11 | addEventListener: THREE.EventDispatcher.prototype.addEventListener, 12 | hasEventListener: THREE.EventDispatcher.prototype.hasEventListener, 13 | removeEventListener: THREE.EventDispatcher.prototype.removeEventListener, 14 | dispatchEvent: THREE.EventDispatcher.prototype.dispatchEvent, 15 | 16 | load: function ( url, callback ) { 17 | 18 | var scope = this; 19 | var request = new XMLHttpRequest(); 20 | 21 | request.addEventListener( 'load', function ( event ) { 22 | 23 | var geometry = scope.parse( event.target.responseText ); 24 | 25 | scope.dispatchEvent( { type: 'load', content: geometry } ); 26 | 27 | if ( callback ) callback( geometry ); 28 | 29 | }, false ); 30 | 31 | request.addEventListener( 'progress', function ( event ) { 32 | 33 | scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } ); 34 | 35 | }, false ); 36 | 37 | request.addEventListener( 'error', function () { 38 | 39 | scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } ); 40 | 41 | }, false ); 42 | 43 | request.open( 'GET', url, true ); 44 | request.send( null ); 45 | 46 | }, 47 | 48 | parse: function ( data ) { 49 | 50 | var geometry = new THREE.Geometry(); 51 | 52 | function vertex( x, y, z ) { 53 | 54 | geometry.vertices.push( new THREE.Vector3( x, y, z ) ); 55 | 56 | } 57 | 58 | function face3( a, b, c ) { 59 | 60 | geometry.faces.push( new THREE.Face3( a, b, c ) ); 61 | 62 | } 63 | 64 | function face4( a, b, c, d ) { 65 | 66 | geometry.faces.push( new THREE.Face4( a, b, c, d ) ); 67 | 68 | } 69 | 70 | var pattern, result; 71 | 72 | // float float float 73 | 74 | pattern = /([\+|\-]?[\d]+[\.][\d|\-|e]+)[ ]+([\+|\-]?[\d]+[\.][\d|\-|e]+)[ ]+([\+|\-]?[\d]+[\.][\d|\-|e]+)/g; 75 | 76 | while ( ( result = pattern.exec( data ) ) != null ) { 77 | 78 | // ["1.0 2.0 3.0", "1.0", "2.0", "3.0"] 79 | 80 | vertex( parseFloat( result[ 1 ] ), parseFloat( result[ 2 ] ), parseFloat( result[ 3 ] ) ); 81 | 82 | } 83 | 84 | // 3 int int int 85 | 86 | pattern = /3[ ]+([\d]+)[ ]+([\d]+)[ ]+([\d]+)/g; 87 | 88 | while ( ( result = pattern.exec( data ) ) != null ) { 89 | 90 | // ["3 1 2 3", "1", "2", "3"] 91 | 92 | face3( parseInt( result[ 1 ] ), parseInt( result[ 2 ] ), parseInt( result[ 3 ] ) ); 93 | 94 | } 95 | 96 | // 4 int int int int 97 | 98 | pattern = /4[ ]+([\d]+)[ ]+([\d]+)[ ]+([\d]+)[ ]+([\d]+)/g; 99 | 100 | while ( ( result = pattern.exec( data ) ) != null ) { 101 | 102 | // ["4 1 2 3 4", "1", "2", "3", "4"] 103 | 104 | face4( parseInt( result[ 1 ] ), parseInt( result[ 2 ] ), parseInt( result[ 3 ] ), parseInt( result[ 4 ] ) ); 105 | 106 | } 107 | 108 | geometry.computeCentroids(); 109 | geometry.computeFaceNormals(); 110 | geometry.computeVertexNormals(); 111 | geometry.computeBoundingSphere(); 112 | 113 | return geometry; 114 | 115 | } 116 | 117 | }; -------------------------------------------------------------------------------- /libs/literally/img/alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/libs/literally/img/alpha.png -------------------------------------------------------------------------------- /libs/literally/img/eraser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/libs/literally/img/eraser.png -------------------------------------------------------------------------------- /libs/literally/img/eyedropper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/libs/literally/img/eyedropper.png -------------------------------------------------------------------------------- /libs/literally/img/hue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/libs/literally/img/hue.png -------------------------------------------------------------------------------- /libs/literally/img/line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/libs/literally/img/line.png -------------------------------------------------------------------------------- /libs/literally/img/pan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/libs/literally/img/pan.png -------------------------------------------------------------------------------- /libs/literally/img/pencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/libs/literally/img/pencil.png -------------------------------------------------------------------------------- /libs/literally/img/rectangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/libs/literally/img/rectangle.png -------------------------------------------------------------------------------- /libs/literally/img/saturation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/libs/literally/img/saturation.png -------------------------------------------------------------------------------- /libs/literally/img/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/libs/literally/img/screenshot.png -------------------------------------------------------------------------------- /libs/postprocessing/BloomPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.BloomPass = function ( strength, kernelSize, sigma, resolution ) { 6 | 7 | strength = ( strength !== undefined ) ? strength : 1; 8 | kernelSize = ( kernelSize !== undefined ) ? kernelSize : 25; 9 | sigma = ( sigma !== undefined ) ? sigma : 4.0; 10 | resolution = ( resolution !== undefined ) ? resolution : 256; 11 | 12 | // render targets 13 | 14 | var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat }; 15 | 16 | this.renderTargetX = new THREE.WebGLRenderTarget( resolution, resolution, pars ); 17 | this.renderTargetY = new THREE.WebGLRenderTarget( resolution, resolution, pars ); 18 | 19 | // copy material 20 | 21 | if ( THREE.CopyShader === undefined ) 22 | console.error( "THREE.BloomPass relies on THREE.CopyShader" ); 23 | 24 | var copyShader = THREE.CopyShader; 25 | 26 | this.copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms ); 27 | 28 | this.copyUniforms[ "opacity" ].value = strength; 29 | 30 | this.materialCopy = new THREE.ShaderMaterial( { 31 | 32 | uniforms: this.copyUniforms, 33 | vertexShader: copyShader.vertexShader, 34 | fragmentShader: copyShader.fragmentShader, 35 | blending: THREE.AdditiveBlending, 36 | transparent: true 37 | 38 | } ); 39 | 40 | // convolution material 41 | 42 | if ( THREE.ConvolutionShader === undefined ) 43 | console.error( "THREE.BloomPass relies on THREE.ConvolutionShader" ); 44 | 45 | var convolutionShader = THREE.ConvolutionShader; 46 | 47 | this.convolutionUniforms = THREE.UniformsUtils.clone( convolutionShader.uniforms ); 48 | 49 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurx; 50 | this.convolutionUniforms[ "cKernel" ].value = THREE.ConvolutionShader.buildKernel( sigma ); 51 | 52 | this.materialConvolution = new THREE.ShaderMaterial( { 53 | 54 | uniforms: this.convolutionUniforms, 55 | vertexShader: convolutionShader.vertexShader, 56 | fragmentShader: convolutionShader.fragmentShader, 57 | defines: { 58 | "KERNEL_SIZE_FLOAT": kernelSize.toFixed( 1 ), 59 | "KERNEL_SIZE_INT": kernelSize.toFixed( 0 ) 60 | } 61 | 62 | } ); 63 | 64 | this.enabled = true; 65 | this.needsSwap = false; 66 | this.clear = false; 67 | 68 | }; 69 | 70 | THREE.BloomPass.prototype = { 71 | 72 | render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { 73 | 74 | if ( maskActive ) renderer.context.disable( renderer.context.STENCIL_TEST ); 75 | 76 | // Render quad with blured scene into texture (convolution pass 1) 77 | 78 | THREE.EffectComposer.quad.material = this.materialConvolution; 79 | 80 | this.convolutionUniforms[ "tDiffuse" ].value = readBuffer; 81 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurX; 82 | 83 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, this.renderTargetX, true ); 84 | 85 | 86 | // Render quad with blured scene into texture (convolution pass 2) 87 | 88 | this.convolutionUniforms[ "tDiffuse" ].value = this.renderTargetX; 89 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurY; 90 | 91 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, this.renderTargetY, true ); 92 | 93 | // Render original scene with superimposed blur to texture 94 | 95 | THREE.EffectComposer.quad.material = this.materialCopy; 96 | 97 | this.copyUniforms[ "tDiffuse" ].value = this.renderTargetY; 98 | 99 | if ( maskActive ) renderer.context.enable( renderer.context.STENCIL_TEST ); 100 | 101 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, readBuffer, this.clear ); 102 | 103 | } 104 | 105 | }; 106 | 107 | THREE.BloomPass.blurX = new THREE.Vector2( 0.001953125, 0.0 ); 108 | THREE.BloomPass.blurY = new THREE.Vector2( 0.0, 0.001953125 ); 109 | -------------------------------------------------------------------------------- /libs/postprocessing/DotScreenPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.DotScreenPass = function ( center, angle, scale ) { 6 | 7 | if ( THREE.DotScreenShader === undefined ) 8 | console.error( "THREE.DotScreenPass relies on THREE.DotScreenShader" ); 9 | 10 | var shader = THREE.DotScreenShader; 11 | 12 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 13 | 14 | if ( center !== undefined ) this.uniforms[ "center" ].value.copy( center ); 15 | if ( angle !== undefined ) this.uniforms[ "angle"].value = angle; 16 | if ( scale !== undefined ) this.uniforms[ "scale"].value = scale; 17 | 18 | this.material = new THREE.ShaderMaterial( { 19 | 20 | uniforms: this.uniforms, 21 | vertexShader: shader.vertexShader, 22 | fragmentShader: shader.fragmentShader 23 | 24 | } ); 25 | 26 | this.enabled = true; 27 | this.renderToScreen = false; 28 | this.needsSwap = true; 29 | 30 | }; 31 | 32 | THREE.DotScreenPass.prototype = { 33 | 34 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 35 | 36 | this.uniforms[ "tDiffuse" ].value = readBuffer; 37 | this.uniforms[ "tSize" ].value.set( readBuffer.width, readBuffer.height ); 38 | 39 | THREE.EffectComposer.quad.material = this.material; 40 | 41 | if ( this.renderToScreen ) { 42 | 43 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera ); 44 | 45 | } else { 46 | 47 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, writeBuffer, false ); 48 | 49 | } 50 | 51 | } 52 | 53 | }; 54 | -------------------------------------------------------------------------------- /libs/postprocessing/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 width = window.innerWidth || 1; 12 | var height = window.innerHeight || 1; 13 | var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false }; 14 | 15 | renderTarget = new THREE.WebGLRenderTarget( width, height, parameters ); 16 | 17 | } 18 | 19 | this.renderTarget1 = renderTarget; 20 | this.renderTarget2 = renderTarget.clone(); 21 | 22 | this.writeBuffer = this.renderTarget1; 23 | this.readBuffer = this.renderTarget2; 24 | 25 | this.passes = []; 26 | 27 | if ( THREE.CopyShader === undefined ) 28 | console.error( "THREE.EffectComposer relies on THREE.CopyShader" ); 29 | 30 | this.copyPass = new THREE.ShaderPass( THREE.CopyShader ); 31 | 32 | }; 33 | 34 | THREE.EffectComposer.prototype = { 35 | 36 | swapBuffers: function() { 37 | 38 | var tmp = this.readBuffer; 39 | this.readBuffer = this.writeBuffer; 40 | this.writeBuffer = tmp; 41 | 42 | }, 43 | 44 | addPass: function ( pass ) { 45 | 46 | this.passes.push( pass ); 47 | 48 | }, 49 | 50 | insertPass: function ( pass, index ) { 51 | 52 | this.passes.splice( index, 0, pass ); 53 | 54 | }, 55 | 56 | render: function ( delta ) { 57 | 58 | this.writeBuffer = this.renderTarget1; 59 | this.readBuffer = this.renderTarget2; 60 | 61 | var maskActive = false; 62 | 63 | var pass, i, il = this.passes.length; 64 | 65 | for ( i = 0; i < il; i ++ ) { 66 | 67 | pass = this.passes[ i ]; 68 | 69 | if ( !pass.enabled ) continue; 70 | 71 | pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive ); 72 | 73 | if ( pass.needsSwap ) { 74 | 75 | if ( maskActive ) { 76 | 77 | var context = this.renderer.context; 78 | 79 | context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff ); 80 | 81 | this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta ); 82 | 83 | context.stencilFunc( context.EQUAL, 1, 0xffffffff ); 84 | 85 | } 86 | 87 | this.swapBuffers(); 88 | 89 | } 90 | 91 | if ( pass instanceof THREE.MaskPass ) { 92 | 93 | maskActive = true; 94 | 95 | } else if ( pass instanceof THREE.ClearMaskPass ) { 96 | 97 | maskActive = false; 98 | 99 | } 100 | 101 | } 102 | 103 | }, 104 | 105 | reset: function ( renderTarget ) { 106 | 107 | if ( renderTarget === undefined ) { 108 | 109 | renderTarget = this.renderTarget1.clone(); 110 | 111 | renderTarget.width = window.innerWidth; 112 | renderTarget.height = window.innerHeight; 113 | 114 | } 115 | 116 | this.renderTarget1 = renderTarget; 117 | this.renderTarget2 = renderTarget.clone(); 118 | 119 | this.writeBuffer = this.renderTarget1; 120 | this.readBuffer = this.renderTarget2; 121 | 122 | }, 123 | 124 | setSize: function ( width, height ) { 125 | 126 | var renderTarget = this.renderTarget1.clone(); 127 | 128 | renderTarget.width = width; 129 | renderTarget.height = height; 130 | 131 | this.reset( renderTarget ); 132 | 133 | } 134 | 135 | }; 136 | 137 | // shared ortho camera 138 | 139 | THREE.EffectComposer.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 ); 140 | 141 | THREE.EffectComposer.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null ); 142 | 143 | THREE.EffectComposer.scene = new THREE.Scene(); 144 | THREE.EffectComposer.scene.add( THREE.EffectComposer.quad ); 145 | -------------------------------------------------------------------------------- /libs/postprocessing/FilmPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.FilmPass = function ( noiseIntensity, scanlinesIntensity, scanlinesCount, grayscale ) { 6 | 7 | if ( THREE.FilmShader === undefined ) 8 | console.error( "THREE.FilmPass relies on THREE.FilmShader" ); 9 | 10 | var shader = THREE.FilmShader; 11 | 12 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 13 | 14 | this.material = new THREE.ShaderMaterial( { 15 | 16 | uniforms: this.uniforms, 17 | vertexShader: shader.vertexShader, 18 | fragmentShader: shader.fragmentShader 19 | 20 | } ); 21 | 22 | if ( grayscale !== undefined ) this.uniforms.grayscale.value = grayscale; 23 | if ( noiseIntensity !== undefined ) this.uniforms.nIntensity.value = noiseIntensity; 24 | if ( scanlinesIntensity !== undefined ) this.uniforms.sIntensity.value = scanlinesIntensity; 25 | if ( scanlinesCount !== undefined ) this.uniforms.sCount.value = scanlinesCount; 26 | 27 | this.enabled = true; 28 | this.renderToScreen = false; 29 | this.needsSwap = true; 30 | 31 | }; 32 | 33 | THREE.FilmPass.prototype = { 34 | 35 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 36 | 37 | this.uniforms[ "tDiffuse" ].value = readBuffer; 38 | this.uniforms[ "time" ].value += delta; 39 | 40 | THREE.EffectComposer.quad.material = this.material; 41 | 42 | if ( this.renderToScreen ) { 43 | 44 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera ); 45 | 46 | } else { 47 | 48 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, writeBuffer, false ); 49 | 50 | } 51 | 52 | } 53 | 54 | }; 55 | -------------------------------------------------------------------------------- /libs/postprocessing/MaskPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.MaskPass = function ( scene, camera ) { 6 | 7 | this.scene = scene; 8 | this.camera = camera; 9 | 10 | this.enabled = true; 11 | this.clear = true; 12 | this.needsSwap = false; 13 | 14 | this.inverse = false; 15 | 16 | }; 17 | 18 | THREE.MaskPass.prototype = { 19 | 20 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 21 | 22 | var context = renderer.context; 23 | 24 | // don't update color or depth 25 | 26 | context.colorMask( false, false, false, false ); 27 | context.depthMask( false ); 28 | 29 | // set up stencil 30 | 31 | var writeValue, clearValue; 32 | 33 | if ( this.inverse ) { 34 | 35 | writeValue = 0; 36 | clearValue = 1; 37 | 38 | } else { 39 | 40 | writeValue = 1; 41 | clearValue = 0; 42 | 43 | } 44 | 45 | context.enable( context.STENCIL_TEST ); 46 | context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE ); 47 | context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff ); 48 | context.clearStencil( clearValue ); 49 | 50 | // draw into the stencil buffer 51 | 52 | renderer.render( this.scene, this.camera, readBuffer, this.clear ); 53 | renderer.render( this.scene, this.camera, writeBuffer, this.clear ); 54 | 55 | // re-enable update of color and depth 56 | 57 | context.colorMask( true, true, true, true ); 58 | context.depthMask( true ); 59 | 60 | // only render where stencil is set to 1 61 | 62 | context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1 63 | context.stencilOp( context.KEEP, context.KEEP, context.KEEP ); 64 | 65 | } 66 | 67 | }; 68 | 69 | 70 | THREE.ClearMaskPass = function () { 71 | 72 | this.enabled = true; 73 | 74 | }; 75 | 76 | THREE.ClearMaskPass.prototype = { 77 | 78 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 79 | 80 | var context = renderer.context; 81 | 82 | context.disable( context.STENCIL_TEST ); 83 | 84 | } 85 | 86 | }; 87 | -------------------------------------------------------------------------------- /libs/postprocessing/RenderPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.RenderPass = function ( scene, camera, overrideMaterial, clearColor, clearAlpha ) { 6 | 7 | this.scene = scene; 8 | this.camera = camera; 9 | 10 | this.overrideMaterial = overrideMaterial; 11 | 12 | this.clearColor = clearColor; 13 | this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1; 14 | 15 | this.oldClearColor = new THREE.Color(); 16 | this.oldClearAlpha = 1; 17 | 18 | this.enabled = true; 19 | this.clear = true; 20 | this.needsSwap = false; 21 | 22 | }; 23 | 24 | THREE.RenderPass.prototype = { 25 | 26 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 27 | 28 | this.scene.overrideMaterial = this.overrideMaterial; 29 | 30 | if ( this.clearColor ) { 31 | 32 | this.oldClearColor.copy( renderer.getClearColor() ); 33 | this.oldClearAlpha = renderer.getClearAlpha(); 34 | 35 | renderer.setClearColor( this.clearColor, this.clearAlpha ); 36 | 37 | } 38 | 39 | renderer.render( this.scene, this.camera, readBuffer, this.clear ); 40 | 41 | if ( this.clearColor ) { 42 | 43 | renderer.setClearColor( this.oldClearColor, this.oldClearAlpha ); 44 | 45 | } 46 | 47 | this.scene.overrideMaterial = null; 48 | 49 | } 50 | 51 | }; 52 | -------------------------------------------------------------------------------- /libs/postprocessing/SavePass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.SavePass = function ( renderTarget ) { 6 | 7 | if ( THREE.CopyShader === undefined ) 8 | console.error( "THREE.SavePass relies on THREE.CopyShader" ); 9 | 10 | var shader = THREE.CopyShader; 11 | 12 | this.textureID = "tDiffuse"; 13 | 14 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 15 | 16 | this.material = new THREE.ShaderMaterial( { 17 | 18 | uniforms: this.uniforms, 19 | vertexShader: shader.vertexShader, 20 | fragmentShader: shader.fragmentShader 21 | 22 | } ); 23 | 24 | this.renderTarget = renderTarget; 25 | 26 | if ( this.renderTarget === undefined ) { 27 | 28 | this.renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false }; 29 | this.renderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, this.renderTargetParameters ); 30 | 31 | } 32 | 33 | this.enabled = true; 34 | this.needsSwap = false; 35 | this.clear = false; 36 | 37 | }; 38 | 39 | THREE.SavePass.prototype = { 40 | 41 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 42 | 43 | if ( this.uniforms[ this.textureID ] ) { 44 | 45 | this.uniforms[ this.textureID ].value = readBuffer; 46 | 47 | } 48 | 49 | THREE.EffectComposer.quad.material = this.material; 50 | 51 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, this.renderTarget, this.clear ); 52 | 53 | } 54 | 55 | }; 56 | -------------------------------------------------------------------------------- /libs/postprocessing/ShaderPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.ShaderPass = function ( shader, textureID ) { 6 | 7 | this.textureID = ( textureID !== undefined ) ? textureID : "tDiffuse"; 8 | 9 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 10 | 11 | this.material = new THREE.ShaderMaterial( { 12 | 13 | uniforms: this.uniforms, 14 | vertexShader: shader.vertexShader, 15 | fragmentShader: shader.fragmentShader 16 | 17 | } ); 18 | 19 | this.renderToScreen = false; 20 | 21 | this.enabled = true; 22 | this.needsSwap = true; 23 | this.clear = false; 24 | 25 | }; 26 | 27 | THREE.ShaderPass.prototype = { 28 | 29 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 30 | 31 | if ( this.uniforms[ this.textureID ] ) { 32 | 33 | this.uniforms[ this.textureID ].value = readBuffer; 34 | 35 | } 36 | 37 | THREE.EffectComposer.quad.material = this.material; 38 | 39 | if ( this.renderToScreen ) { 40 | 41 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera ); 42 | 43 | } else { 44 | 45 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, writeBuffer, this.clear ); 46 | 47 | } 48 | 49 | } 50 | 51 | }; 52 | -------------------------------------------------------------------------------- /libs/postprocessing/TexturePass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.TexturePass = function ( texture, opacity ) { 6 | 7 | if ( THREE.CopyShader === undefined ) 8 | console.error( "THREE.TexturePass relies on THREE.CopyShader" ); 9 | 10 | var shader = THREE.CopyShader; 11 | 12 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 13 | 14 | this.uniforms[ "opacity" ].value = ( opacity !== undefined ) ? opacity : 1.0; 15 | this.uniforms[ "tDiffuse" ].value = texture; 16 | 17 | this.material = new THREE.ShaderMaterial( { 18 | 19 | uniforms: this.uniforms, 20 | vertexShader: shader.vertexShader, 21 | fragmentShader: shader.fragmentShader 22 | 23 | } ); 24 | 25 | this.enabled = true; 26 | this.needsSwap = false; 27 | 28 | }; 29 | 30 | THREE.TexturePass.prototype = { 31 | 32 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 33 | 34 | THREE.EffectComposer.quad.material = this.material; 35 | 36 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, readBuffer ); 37 | 38 | } 39 | 40 | }; 41 | -------------------------------------------------------------------------------- /libs/shaders/BasicShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://www.mrdoob.com 3 | * 4 | * Simple test shader 5 | */ 6 | 7 | THREE.BasicShader = { 8 | 9 | uniforms: {}, 10 | 11 | vertexShader: [ 12 | 13 | "void main() {", 14 | 15 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 16 | 17 | "}" 18 | 19 | ].join("\n"), 20 | 21 | fragmentShader: [ 22 | 23 | "void main() {", 24 | 25 | "gl_FragColor = vec4( 1.0, 0.0, 0.0, 0.5 );", 26 | 27 | "}" 28 | 29 | ].join("\n") 30 | 31 | }; 32 | -------------------------------------------------------------------------------- /libs/shaders/BleachBypassShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Bleach bypass shader [http://en.wikipedia.org/wiki/Bleach_bypass] 5 | * - based on Nvidia example 6 | * http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html#post_bleach_bypass 7 | */ 8 | 9 | THREE.BleachBypassShader = { 10 | 11 | uniforms: { 12 | 13 | "tDiffuse": { type: "t", value: null }, 14 | "opacity": { type: "f", value: 1.0 } 15 | 16 | }, 17 | 18 | vertexShader: [ 19 | 20 | "varying vec2 vUv;", 21 | 22 | "void main() {", 23 | 24 | "vUv = uv;", 25 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 26 | 27 | "}" 28 | 29 | ].join("\n"), 30 | 31 | fragmentShader: [ 32 | 33 | "uniform float opacity;", 34 | 35 | "uniform sampler2D tDiffuse;", 36 | 37 | "varying vec2 vUv;", 38 | 39 | "void main() {", 40 | 41 | "vec4 base = texture2D( tDiffuse, vUv );", 42 | 43 | "vec3 lumCoeff = vec3( 0.25, 0.65, 0.1 );", 44 | "float lum = dot( lumCoeff, base.rgb );", 45 | "vec3 blend = vec3( lum );", 46 | 47 | "float L = min( 1.0, max( 0.0, 10.0 * ( lum - 0.45 ) ) );", 48 | 49 | "vec3 result1 = 2.0 * base.rgb * blend;", 50 | "vec3 result2 = 1.0 - 2.0 * ( 1.0 - blend ) * ( 1.0 - base.rgb );", 51 | 52 | "vec3 newColor = mix( result1, result2, L );", 53 | 54 | "float A2 = opacity * base.a;", 55 | "vec3 mixRGB = A2 * newColor.rgb;", 56 | "mixRGB += ( ( 1.0 - A2 ) * base.rgb );", 57 | 58 | "gl_FragColor = vec4( mixRGB, base.a );", 59 | 60 | "}" 61 | 62 | ].join("\n") 63 | 64 | }; 65 | -------------------------------------------------------------------------------- /libs/shaders/BlendShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Blend two textures 5 | */ 6 | 7 | THREE.BlendShader = { 8 | 9 | uniforms: { 10 | 11 | "tDiffuse1": { type: "t", value: null }, 12 | "tDiffuse2": { type: "t", value: null }, 13 | "mixRatio": { type: "f", value: 0.5 }, 14 | "opacity": { type: "f", value: 1.0 } 15 | 16 | }, 17 | 18 | vertexShader: [ 19 | 20 | "varying vec2 vUv;", 21 | 22 | "void main() {", 23 | 24 | "vUv = uv;", 25 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 26 | 27 | "}" 28 | 29 | ].join("\n"), 30 | 31 | fragmentShader: [ 32 | 33 | "uniform float opacity;", 34 | "uniform float mixRatio;", 35 | 36 | "uniform sampler2D tDiffuse1;", 37 | "uniform sampler2D tDiffuse2;", 38 | 39 | "varying vec2 vUv;", 40 | 41 | "void main() {", 42 | 43 | "vec4 texel1 = texture2D( tDiffuse1, vUv );", 44 | "vec4 texel2 = texture2D( tDiffuse2, vUv );", 45 | "gl_FragColor = opacity * mix( texel1, texel2, mixRatio );", 46 | 47 | "}" 48 | 49 | ].join("\n") 50 | 51 | }; 52 | -------------------------------------------------------------------------------- /libs/shaders/BokehShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Depth-of-field shader with bokeh 5 | * ported from GLSL shader by Martins Upitis 6 | * http://artmartinsh.blogspot.com/2010/02/glsl-lens-blur-filter-with-bokeh.html 7 | */ 8 | 9 | THREE.BokehShader = { 10 | 11 | uniforms: { 12 | 13 | "tColor": { type: "t", value: null }, 14 | "tDepth": { type: "t", value: null }, 15 | "focus": { type: "f", value: 1.0 }, 16 | "aspect": { type: "f", value: 1.0 }, 17 | "aperture": { type: "f", value: 0.025 }, 18 | "maxblur": { type: "f", value: 1.0 } 19 | 20 | }, 21 | 22 | vertexShader: [ 23 | 24 | "varying vec2 vUv;", 25 | 26 | "void main() {", 27 | 28 | "vUv = uv;", 29 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 30 | 31 | "}" 32 | 33 | ].join("\n"), 34 | 35 | fragmentShader: [ 36 | 37 | "varying vec2 vUv;", 38 | 39 | "uniform sampler2D tColor;", 40 | "uniform sampler2D tDepth;", 41 | 42 | "uniform float maxblur;", // max blur amount 43 | "uniform float aperture;", // aperture - bigger values for shallower depth of field 44 | 45 | "uniform float focus;", 46 | "uniform float aspect;", 47 | 48 | "void main() {", 49 | 50 | "vec2 aspectcorrect = vec2( 1.0, aspect );", 51 | 52 | "vec4 depth1 = texture2D( tDepth, vUv );", 53 | 54 | "float factor = depth1.x - focus;", 55 | 56 | "vec2 dofblur = vec2 ( clamp( factor * aperture, -maxblur, maxblur ) );", 57 | 58 | "vec2 dofblur9 = dofblur * 0.9;", 59 | "vec2 dofblur7 = dofblur * 0.7;", 60 | "vec2 dofblur4 = dofblur * 0.4;", 61 | 62 | "vec4 col = vec4( 0.0 );", 63 | 64 | "col += texture2D( tColor, vUv.xy );", 65 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur );", 66 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur );", 67 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur );", 68 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur );", 69 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur );", 70 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur );", 71 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur );", 72 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur );", 73 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur );", 74 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur );", 75 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur );", 76 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur );", 77 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur );", 78 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur );", 79 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur );", 80 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur );", 81 | 82 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur9 );", 83 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur9 );", 84 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur9 );", 85 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur9 );", 86 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur9 );", 87 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur9 );", 88 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur9 );", 89 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur9 );", 90 | 91 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur7 );", 92 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur7 );", 93 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur7 );", 94 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur7 );", 95 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur7 );", 96 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur7 );", 97 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur7 );", 98 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur7 );", 99 | 100 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur4 );", 101 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.4, 0.0 ) * aspectcorrect ) * dofblur4 );", 102 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur4 );", 103 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur4 );", 104 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur4 );", 105 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur4 );", 106 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur4 );", 107 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur4 );", 108 | 109 | "gl_FragColor = col / 41.0;", 110 | "gl_FragColor.a = 1.0;", 111 | 112 | "}" 113 | 114 | ].join("\n") 115 | 116 | }; 117 | -------------------------------------------------------------------------------- /libs/shaders/BrightnessContrastShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author tapio / http://tapio.github.com/ 3 | * 4 | * Brightness and contrast adjustment 5 | * https://github.com/evanw/glfx.js 6 | * brightness: -1 to 1 (-1 is solid black, 0 is no change, and 1 is solid white) 7 | * contrast: -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast) 8 | */ 9 | 10 | THREE.BrightnessContrastShader = { 11 | 12 | uniforms: { 13 | 14 | "tDiffuse": { type: "t", value: null }, 15 | "brightness": { type: "f", value: 0 }, 16 | "contrast": { type: "f", value: 0 } 17 | 18 | }, 19 | 20 | vertexShader: [ 21 | 22 | "varying vec2 vUv;", 23 | 24 | "void main() {", 25 | 26 | "vUv = uv;", 27 | 28 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 29 | 30 | "}" 31 | 32 | ].join("\n"), 33 | 34 | fragmentShader: [ 35 | 36 | "uniform sampler2D tDiffuse;", 37 | "uniform float brightness;", 38 | "uniform float contrast;", 39 | 40 | "varying vec2 vUv;", 41 | 42 | "void main() {", 43 | 44 | "gl_FragColor = texture2D( tDiffuse, vUv );", 45 | 46 | "gl_FragColor.rgb += brightness;", 47 | 48 | "if (contrast > 0.0) {", 49 | "gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) / (1.0 - contrast) + 0.5;", 50 | "} else {", 51 | "gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) * (1.0 + contrast) + 0.5;", 52 | "}", 53 | 54 | "}" 55 | 56 | ].join("\n") 57 | 58 | }; 59 | -------------------------------------------------------------------------------- /libs/shaders/ColorCorrectionShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Color correction 5 | */ 6 | 7 | THREE.ColorCorrectionShader = { 8 | 9 | uniforms: { 10 | 11 | "tDiffuse": { type: "t", value: null }, 12 | "powRGB": { type: "v3", value: new THREE.Vector3( 2, 2, 2 ) }, 13 | "mulRGB": { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) } 14 | 15 | }, 16 | 17 | vertexShader: [ 18 | 19 | "varying vec2 vUv;", 20 | 21 | "void main() {", 22 | 23 | "vUv = uv;", 24 | 25 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 26 | 27 | "}" 28 | 29 | ].join("\n"), 30 | 31 | fragmentShader: [ 32 | 33 | "uniform sampler2D tDiffuse;", 34 | "uniform vec3 powRGB;", 35 | "uniform vec3 mulRGB;", 36 | 37 | "varying vec2 vUv;", 38 | 39 | "void main() {", 40 | 41 | "gl_FragColor = texture2D( tDiffuse, vUv );", 42 | "gl_FragColor.rgb = mulRGB * pow( gl_FragColor.rgb, powRGB );", 43 | 44 | "}" 45 | 46 | ].join("\n") 47 | 48 | }; 49 | -------------------------------------------------------------------------------- /libs/shaders/ColorifyShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Colorify shader 5 | */ 6 | 7 | THREE.ColorifyShader = { 8 | 9 | uniforms: { 10 | 11 | "tDiffuse": { type: "t", value: null }, 12 | "color": { type: "c", value: new THREE.Color( 0xffffff ) } 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 vec3 color;", 32 | "uniform sampler2D tDiffuse;", 33 | 34 | "varying vec2 vUv;", 35 | 36 | "void main() {", 37 | 38 | "vec4 texel = texture2D( tDiffuse, vUv );", 39 | 40 | "vec3 luma = vec3( 0.299, 0.587, 0.114 );", 41 | "float v = dot( texel.xyz, luma );", 42 | 43 | "gl_FragColor = vec4( v * color, texel.w );", 44 | 45 | "}" 46 | 47 | ].join("\n") 48 | 49 | }; 50 | -------------------------------------------------------------------------------- /libs/shaders/ConvolutionShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Convolution shader 5 | * ported from o3d sample to WebGL / GLSL 6 | * http://o3d.googlecode.com/svn/trunk/samples/convolution.html 7 | */ 8 | 9 | THREE.ConvolutionShader = { 10 | 11 | defines: { 12 | 13 | "KERNEL_SIZE_FLOAT": "25.0", 14 | "KERNEL_SIZE_INT": "25", 15 | 16 | }, 17 | 18 | uniforms: { 19 | 20 | "tDiffuse": { type: "t", value: null }, 21 | "uImageIncrement": { type: "v2", value: new THREE.Vector2( 0.001953125, 0.0 ) }, 22 | "cKernel": { type: "fv1", value: [] } 23 | 24 | }, 25 | 26 | vertexShader: [ 27 | 28 | "uniform vec2 uImageIncrement;", 29 | 30 | "varying vec2 vUv;", 31 | 32 | "void main() {", 33 | 34 | "vUv = uv - ( ( KERNEL_SIZE_FLOAT - 1.0 ) / 2.0 ) * uImageIncrement;", 35 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 36 | 37 | "}" 38 | 39 | ].join("\n"), 40 | 41 | fragmentShader: [ 42 | 43 | "uniform float cKernel[ KERNEL_SIZE_INT ];", 44 | 45 | "uniform sampler2D tDiffuse;", 46 | "uniform vec2 uImageIncrement;", 47 | 48 | "varying vec2 vUv;", 49 | 50 | "void main() {", 51 | 52 | "vec2 imageCoord = vUv;", 53 | "vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );", 54 | 55 | "for( int i = 0; i < KERNEL_SIZE_INT; i ++ ) {", 56 | 57 | "sum += texture2D( tDiffuse, imageCoord ) * cKernel[ i ];", 58 | "imageCoord += uImageIncrement;", 59 | 60 | "}", 61 | 62 | "gl_FragColor = sum;", 63 | 64 | "}" 65 | 66 | 67 | ].join("\n"), 68 | 69 | buildKernel: function ( sigma ) { 70 | 71 | // We lop off the sqrt(2 * pi) * sigma term, since we're going to normalize anyway. 72 | 73 | function gauss( x, sigma ) { 74 | 75 | return Math.exp( - ( x * x ) / ( 2.0 * sigma * sigma ) ); 76 | 77 | } 78 | 79 | var i, values, sum, halfWidth, kMaxKernelSize = 25, kernelSize = 2 * Math.ceil( sigma * 3.0 ) + 1; 80 | 81 | if ( kernelSize > kMaxKernelSize ) kernelSize = kMaxKernelSize; 82 | halfWidth = ( kernelSize - 1 ) * 0.5; 83 | 84 | values = new Array( kernelSize ); 85 | sum = 0.0; 86 | for ( i = 0; i < kernelSize; ++i ) { 87 | 88 | values[ i ] = gauss( i - halfWidth, sigma ); 89 | sum += values[ i ]; 90 | 91 | } 92 | 93 | // normalize the kernel 94 | 95 | for ( i = 0; i < kernelSize; ++i ) values[ i ] /= sum; 96 | 97 | return values; 98 | 99 | } 100 | 101 | }; 102 | -------------------------------------------------------------------------------- /libs/shaders/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": { type: "t", value: null }, 12 | "opacity": { type: "f", 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 | -------------------------------------------------------------------------------- /libs/shaders/DOFMipMapShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Depth-of-field shader using mipmaps 5 | * - from Matt Handley @applmak 6 | * - requires power-of-2 sized render target with enabled mipmaps 7 | */ 8 | 9 | THREE.DOFMipMapShader = { 10 | 11 | uniforms: { 12 | 13 | "tColor": { type: "t", value: null }, 14 | "tDepth": { type: "t", value: null }, 15 | "focus": { type: "f", value: 1.0 }, 16 | "maxblur": { type: "f", value: 1.0 } 17 | 18 | }, 19 | 20 | vertexShader: [ 21 | 22 | "varying vec2 vUv;", 23 | 24 | "void main() {", 25 | 26 | "vUv = uv;", 27 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 28 | 29 | "}" 30 | 31 | ].join("\n"), 32 | 33 | fragmentShader: [ 34 | 35 | "uniform float focus;", 36 | "uniform float maxblur;", 37 | 38 | "uniform sampler2D tColor;", 39 | "uniform sampler2D tDepth;", 40 | 41 | "varying vec2 vUv;", 42 | 43 | "void main() {", 44 | 45 | "vec4 depth = texture2D( tDepth, vUv );", 46 | 47 | "float factor = depth.x - focus;", 48 | 49 | "vec4 col = texture2D( tColor, vUv, 2.0 * maxblur * abs( focus - depth.x ) );", 50 | 51 | "gl_FragColor = col;", 52 | "gl_FragColor.a = 1.0;", 53 | 54 | "}" 55 | 56 | ].join("\n") 57 | 58 | }; 59 | -------------------------------------------------------------------------------- /libs/shaders/DotScreenShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Dot screen shader 5 | * based on glfx.js sepia shader 6 | * https://github.com/evanw/glfx.js 7 | */ 8 | 9 | THREE.DotScreenShader = { 10 | 11 | uniforms: { 12 | 13 | "tDiffuse": { type: "t", value: null }, 14 | "tSize": { type: "v2", value: new THREE.Vector2( 256, 256 ) }, 15 | "center": { type: "v2", value: new THREE.Vector2( 0.5, 0.5 ) }, 16 | "angle": { type: "f", value: 1.57 }, 17 | "scale": { type: "f", value: 1.0 } 18 | 19 | }, 20 | 21 | vertexShader: [ 22 | 23 | "varying vec2 vUv;", 24 | 25 | "void main() {", 26 | 27 | "vUv = uv;", 28 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 29 | 30 | "}" 31 | 32 | ].join("\n"), 33 | 34 | fragmentShader: [ 35 | 36 | "uniform vec2 center;", 37 | "uniform float angle;", 38 | "uniform float scale;", 39 | "uniform vec2 tSize;", 40 | 41 | "uniform sampler2D tDiffuse;", 42 | 43 | "varying vec2 vUv;", 44 | 45 | "float pattern() {", 46 | 47 | "float s = sin( angle ), c = cos( angle );", 48 | 49 | "vec2 tex = vUv * tSize - center;", 50 | "vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale;", 51 | 52 | "return ( sin( point.x ) * sin( point.y ) ) * 4.0;", 53 | 54 | "}", 55 | 56 | "void main() {", 57 | 58 | "vec4 color = texture2D( tDiffuse, vUv );", 59 | 60 | "float average = ( color.r + color.g + color.b ) / 3.0;", 61 | 62 | "gl_FragColor = vec4( vec3( average * 10.0 - 5.0 + pattern() ), color.a );", 63 | 64 | "}" 65 | 66 | ].join("\n") 67 | 68 | }; 69 | -------------------------------------------------------------------------------- /libs/shaders/EdgeShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author zz85 / https://github.com/zz85 | https://www.lab4games.net/zz85/blog 3 | * 4 | * Edge Detection Shader using Frei-Chen filter 5 | * Based on http://rastergrid.com/blog/2011/01/frei-chen-edge-detector 6 | * 7 | * aspect: vec2 of (1/width, 1/height) 8 | */ 9 | 10 | THREE.EdgeShader = { 11 | 12 | uniforms: { 13 | 14 | "tDiffuse": { type: "t", value: null }, 15 | "aspect": { type: "v2", value: new THREE.Vector2( 512, 512 ) }, 16 | }, 17 | 18 | vertexShader: [ 19 | 20 | "varying vec2 vUv;", 21 | 22 | "void main() {", 23 | 24 | "vUv = uv;", 25 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 26 | 27 | "}" 28 | 29 | ].join("\n"), 30 | 31 | fragmentShader: [ 32 | 33 | "uniform sampler2D tDiffuse;", 34 | "varying vec2 vUv;", 35 | 36 | "uniform vec2 aspect;", 37 | 38 | "vec2 texel = vec2(1.0 / aspect.x, 1.0 / aspect.y);", 39 | 40 | 41 | "mat3 G[9];", 42 | 43 | // hard coded matrix values!!!! as suggested in https://github.com/neilmendoza/ofxPostProcessing/blob/master/src/EdgePass.cpp#L45 44 | 45 | "const mat3 g0 = mat3( 0.3535533845424652, 0, -0.3535533845424652, 0.5, 0, -0.5, 0.3535533845424652, 0, -0.3535533845424652 );", 46 | "const mat3 g1 = mat3( 0.3535533845424652, 0.5, 0.3535533845424652, 0, 0, 0, -0.3535533845424652, -0.5, -0.3535533845424652 );", 47 | "const mat3 g2 = mat3( 0, 0.3535533845424652, -0.5, -0.3535533845424652, 0, 0.3535533845424652, 0.5, -0.3535533845424652, 0 );", 48 | "const mat3 g3 = mat3( 0.5, -0.3535533845424652, 0, -0.3535533845424652, 0, 0.3535533845424652, 0, 0.3535533845424652, -0.5 );", 49 | "const mat3 g4 = mat3( 0, -0.5, 0, 0.5, 0, 0.5, 0, -0.5, 0 );", 50 | "const mat3 g5 = mat3( -0.5, 0, 0.5, 0, 0, 0, 0.5, 0, -0.5 );", 51 | "const mat3 g6 = mat3( 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.6666666865348816, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204 );", 52 | "const mat3 g7 = mat3( -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, 0.6666666865348816, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408 );", 53 | "const mat3 g8 = mat3( 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408 );", 54 | 55 | "void main(void)", 56 | "{", 57 | 58 | "G[0] = g0,", 59 | "G[1] = g1,", 60 | "G[2] = g2,", 61 | "G[3] = g3,", 62 | "G[4] = g4,", 63 | "G[5] = g5,", 64 | "G[6] = g6,", 65 | "G[7] = g7,", 66 | "G[8] = g8;", 67 | 68 | "mat3 I;", 69 | "float cnv[9];", 70 | "vec3 sample;", 71 | 72 | /* fetch the 3x3 neighbourhood and use the RGB vector's length as intensity value */ 73 | "for (float i=0.0; i<3.0; i++) {", 74 | "for (float j=0.0; j<3.0; j++) {", 75 | "sample = texture2D(tDiffuse, vUv + texel * vec2(i-1.0,j-1.0) ).rgb;", 76 | "I[int(i)][int(j)] = length(sample);", 77 | "}", 78 | "}", 79 | 80 | /* calculate the convolution values for all the masks */ 81 | "for (int i=0; i<9; i++) {", 82 | "float dp3 = dot(G[i][0], I[0]) + dot(G[i][1], I[1]) + dot(G[i][2], I[2]);", 83 | "cnv[i] = dp3 * dp3;", 84 | "}", 85 | 86 | "float M = (cnv[0] + cnv[1]) + (cnv[2] + cnv[3]);", 87 | "float S = (cnv[4] + cnv[5]) + (cnv[6] + cnv[7]) + (cnv[8] + M);", 88 | 89 | "gl_FragColor = vec4(vec3(sqrt(M/S)), 1.0);", 90 | "}", 91 | 92 | ].join("\n") 93 | }; 94 | -------------------------------------------------------------------------------- /libs/shaders/EdgeShader2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author zz85 / https://github.com/zz85 | https://www.lab4games.net/zz85/blog 3 | * 4 | * Edge Detection Shader using Sobel filter 5 | * Based on http://rastergrid.com/blog/2011/01/frei-chen-edge-detector 6 | * 7 | * aspect: vec2 of (1/width, 1/height) 8 | */ 9 | 10 | THREE.EdgeShader2 = { 11 | 12 | uniforms: { 13 | 14 | "tDiffuse": { type: "t", value: null }, 15 | "aspect": { type: "v2", value: new THREE.Vector2( 512, 512 ) }, 16 | }, 17 | 18 | vertexShader: [ 19 | 20 | "varying vec2 vUv;", 21 | 22 | "void main() {", 23 | 24 | "vUv = uv;", 25 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 26 | 27 | "}" 28 | 29 | ].join("\n"), 30 | 31 | fragmentShader: [ 32 | 33 | "uniform sampler2D tDiffuse;", 34 | "varying vec2 vUv;", 35 | "uniform vec2 aspect;", 36 | 37 | 38 | "vec2 texel = vec2(1.0 / aspect.x, 1.0 / aspect.y);", 39 | 40 | "mat3 G[2];", 41 | 42 | "const mat3 g0 = mat3( 1.0, 2.0, 1.0, 0.0, 0.0, 0.0, -1.0, -2.0, -1.0 );", 43 | "const mat3 g1 = mat3( 1.0, 0.0, -1.0, 2.0, 0.0, -2.0, 1.0, 0.0, -1.0 );", 44 | 45 | 46 | "void main(void)", 47 | "{", 48 | "mat3 I;", 49 | "float cnv[2];", 50 | "vec3 sample;", 51 | 52 | "G[0] = g0;", 53 | "G[1] = g1;", 54 | 55 | /* fetch the 3x3 neighbourhood and use the RGB vector's length as intensity value */ 56 | "for (float i=0.0; i<3.0; i++)", 57 | "for (float j=0.0; j<3.0; j++) {", 58 | "sample = texture2D( tDiffuse, vUv + texel * vec2(i-1.0,j-1.0) ).rgb;", 59 | "I[int(i)][int(j)] = length(sample);", 60 | "}", 61 | 62 | /* calculate the convolution values for all the masks */ 63 | "for (int i=0; i<2; i++) {", 64 | "float dp3 = dot(G[i][0], I[0]) + dot(G[i][1], I[1]) + dot(G[i][2], I[2]);", 65 | "cnv[i] = dp3 * dp3; ", 66 | "}", 67 | 68 | "gl_FragColor = vec4(0.5 * sqrt(cnv[0]*cnv[0]+cnv[1]*cnv[1]));", 69 | "} ", 70 | 71 | ].join("\n") 72 | 73 | }; 74 | -------------------------------------------------------------------------------- /libs/shaders/FXAAShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * @author davidedc / http://www.sketchpatch.net/ 4 | * 5 | * NVIDIA FXAA by Timothy Lottes 6 | * http://timothylottes.blogspot.com/2011/06/fxaa3-source-released.html 7 | * - WebGL port by @supereggbert 8 | * http://www.glge.org/demos/fxaa/ 9 | */ 10 | 11 | THREE.FXAAShader = { 12 | 13 | uniforms: { 14 | 15 | "tDiffuse": { type: "t", value: null }, 16 | "resolution": { type: "v2", value: new THREE.Vector2( 1 / 1024, 1 / 512 ) } 17 | 18 | }, 19 | 20 | vertexShader: [ 21 | 22 | "varying vec2 vUv;", 23 | 24 | "void main() {", 25 | 26 | "vUv = uv;", 27 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 28 | 29 | "}" 30 | 31 | ].join("\n"), 32 | 33 | fragmentShader: [ 34 | 35 | "uniform sampler2D tDiffuse;", 36 | "uniform vec2 resolution;", 37 | 38 | "varying vec2 vUv;", 39 | 40 | "#define FXAA_REDUCE_MIN (1.0/128.0)", 41 | "#define FXAA_REDUCE_MUL (1.0/8.0)", 42 | "#define FXAA_SPAN_MAX 8.0", 43 | 44 | "void main() {", 45 | 46 | "vec3 rgbNW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ).xyz;", 47 | "vec3 rgbNE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ).xyz;", 48 | "vec3 rgbSW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ).xyz;", 49 | "vec3 rgbSE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ).xyz;", 50 | "vec4 rgbaM = texture2D( tDiffuse, gl_FragCoord.xy * resolution );", 51 | "vec3 rgbM = rgbaM.xyz;", 52 | "float opacity = rgbaM.w;", 53 | 54 | "vec3 luma = vec3( 0.299, 0.587, 0.114 );", 55 | 56 | "float lumaNW = dot( rgbNW, luma );", 57 | "float lumaNE = dot( rgbNE, luma );", 58 | "float lumaSW = dot( rgbSW, luma );", 59 | "float lumaSE = dot( rgbSE, luma );", 60 | "float lumaM = dot( rgbM, luma );", 61 | "float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );", 62 | "float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );", 63 | 64 | "vec2 dir;", 65 | "dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));", 66 | "dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));", 67 | 68 | "float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );", 69 | 70 | "float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );", 71 | "dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),", 72 | "max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),", 73 | "dir * rcpDirMin)) * resolution;", 74 | 75 | "vec3 rgbA = 0.5 * (", 76 | "texture2D( tDiffuse, gl_FragCoord.xy * resolution + dir * ( 1.0 / 3.0 - 0.5 ) ).xyz +", 77 | "texture2D( tDiffuse, gl_FragCoord.xy * resolution + dir * ( 2.0 / 3.0 - 0.5 ) ).xyz );", 78 | 79 | "vec3 rgbB = rgbA * 0.5 + 0.25 * (", 80 | "texture2D( tDiffuse, gl_FragCoord.xy * resolution + dir * -0.5 ).xyz +", 81 | "texture2D( tDiffuse, gl_FragCoord.xy * resolution + dir * 0.5 ).xyz );", 82 | 83 | "float lumaB = dot( rgbB, luma );", 84 | 85 | "if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) {", 86 | 87 | "gl_FragColor = vec4( rgbA, opacity );", 88 | 89 | "} else {", 90 | 91 | "gl_FragColor = vec4( rgbB, opacity );", 92 | 93 | "}", 94 | 95 | "}" 96 | 97 | ].join("\n") 98 | 99 | }; 100 | -------------------------------------------------------------------------------- /libs/shaders/FilmShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Film grain & scanlines shader 5 | * 6 | * - ported from HLSL to WebGL / GLSL 7 | * http://www.truevision3d.com/forums/showcase/staticnoise_colorblackwhite_scanline_shaders-t18698.0.html 8 | * 9 | * Screen Space Static Postprocessor 10 | * 11 | * Produces an analogue noise overlay similar to a film grain / TV static 12 | * 13 | * Original implementation and noise algorithm 14 | * Pat 'Hawthorne' Shearon 15 | * 16 | * Optimized scanlines + noise version with intensity scaling 17 | * Georg 'Leviathan' Steinrohder 18 | * 19 | * This version is provided under a Creative Commons Attribution 3.0 License 20 | * http://creativecommons.org/licenses/by/3.0/ 21 | */ 22 | 23 | THREE.FilmShader = { 24 | 25 | uniforms: { 26 | 27 | "tDiffuse": { type: "t", value: null }, 28 | "time": { type: "f", value: 0.0 }, 29 | "nIntensity": { type: "f", value: 0.5 }, 30 | "sIntensity": { type: "f", value: 0.05 }, 31 | "sCount": { type: "f", value: 4096 }, 32 | "grayscale": { type: "i", value: 1 } 33 | 34 | }, 35 | 36 | vertexShader: [ 37 | 38 | "varying vec2 vUv;", 39 | 40 | "void main() {", 41 | 42 | "vUv = uv;", 43 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 44 | 45 | "}" 46 | 47 | ].join("\n"), 48 | 49 | fragmentShader: [ 50 | 51 | // control parameter 52 | "uniform float time;", 53 | 54 | "uniform bool grayscale;", 55 | 56 | // noise effect intensity value (0 = no effect, 1 = full effect) 57 | "uniform float nIntensity;", 58 | 59 | // scanlines effect intensity value (0 = no effect, 1 = full effect) 60 | "uniform float sIntensity;", 61 | 62 | // scanlines effect count value (0 = no effect, 4096 = full effect) 63 | "uniform float sCount;", 64 | 65 | "uniform sampler2D tDiffuse;", 66 | 67 | "varying vec2 vUv;", 68 | 69 | "void main() {", 70 | 71 | // sample the source 72 | "vec4 cTextureScreen = texture2D( tDiffuse, vUv );", 73 | 74 | // make some noise 75 | "float x = vUv.x * vUv.y * time * 1000.0;", 76 | "x = mod( x, 13.0 ) * mod( x, 123.0 );", 77 | "float dx = mod( x, 0.01 );", 78 | 79 | // add noise 80 | "vec3 cResult = cTextureScreen.rgb + cTextureScreen.rgb * clamp( 0.1 + dx * 100.0, 0.0, 1.0 );", 81 | 82 | // get us a sine and cosine 83 | "vec2 sc = vec2( sin( vUv.y * sCount ), cos( vUv.y * sCount ) );", 84 | 85 | // add scanlines 86 | "cResult += cTextureScreen.rgb * vec3( sc.x, sc.y, sc.x ) * sIntensity;", 87 | 88 | // interpolate between source and result by intensity 89 | "cResult = cTextureScreen.rgb + clamp( nIntensity, 0.0,1.0 ) * ( cResult - cTextureScreen.rgb );", 90 | 91 | // convert to grayscale if desired 92 | "if( grayscale ) {", 93 | 94 | "cResult = vec3( cResult.r * 0.3 + cResult.g * 0.59 + cResult.b * 0.11 );", 95 | 96 | "}", 97 | 98 | "gl_FragColor = vec4( cResult, cTextureScreen.a );", 99 | 100 | "}" 101 | 102 | ].join("\n") 103 | 104 | }; 105 | -------------------------------------------------------------------------------- /libs/shaders/FocusShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Focus shader 5 | * based on PaintEffect postprocess from ro.me 6 | * http://code.google.com/p/3-dreams-of-black/source/browse/deploy/js/effects/PaintEffect.js 7 | */ 8 | 9 | THREE.FocusShader = { 10 | 11 | uniforms : { 12 | 13 | "tDiffuse": { type: "t", value: null }, 14 | "screenWidth": { type: "f", value: 1024 }, 15 | "screenHeight": { type: "f", value: 1024 }, 16 | "sampleDistance": { type: "f", value: 0.94 }, 17 | "waveFactor": { type: "f", value: 0.00125 } 18 | 19 | }, 20 | 21 | vertexShader: [ 22 | 23 | "varying vec2 vUv;", 24 | 25 | "void main() {", 26 | 27 | "vUv = uv;", 28 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 29 | 30 | "}" 31 | 32 | ].join("\n"), 33 | 34 | fragmentShader: [ 35 | 36 | "uniform float screenWidth;", 37 | "uniform float screenHeight;", 38 | "uniform float sampleDistance;", 39 | "uniform float waveFactor;", 40 | 41 | "uniform sampler2D tDiffuse;", 42 | 43 | "varying vec2 vUv;", 44 | 45 | "void main() {", 46 | 47 | "vec4 color, org, tmp, add;", 48 | "float sample_dist, f;", 49 | "vec2 vin;", 50 | "vec2 uv = vUv;", 51 | 52 | "add = color = org = texture2D( tDiffuse, uv );", 53 | 54 | "vin = ( uv - vec2( 0.5 ) ) * vec2( 1.4 );", 55 | "sample_dist = dot( vin, vin ) * 2.0;", 56 | 57 | "f = ( waveFactor * 100.0 + sample_dist ) * sampleDistance * 4.0;", 58 | 59 | "vec2 sampleSize = vec2( 1.0 / screenWidth, 1.0 / screenHeight ) * vec2( f );", 60 | 61 | "add += tmp = texture2D( tDiffuse, uv + vec2( 0.111964, 0.993712 ) * sampleSize );", 62 | "if( tmp.b < color.b ) color = tmp;", 63 | 64 | "add += tmp = texture2D( tDiffuse, uv + vec2( 0.846724, 0.532032 ) * sampleSize );", 65 | "if( tmp.b < color.b ) color = tmp;", 66 | 67 | "add += tmp = texture2D( tDiffuse, uv + vec2( 0.943883, -0.330279 ) * sampleSize );", 68 | "if( tmp.b < color.b ) color = tmp;", 69 | 70 | "add += tmp = texture2D( tDiffuse, uv + vec2( 0.330279, -0.943883 ) * sampleSize );", 71 | "if( tmp.b < color.b ) color = tmp;", 72 | 73 | "add += tmp = texture2D( tDiffuse, uv + vec2( -0.532032, -0.846724 ) * sampleSize );", 74 | "if( tmp.b < color.b ) color = tmp;", 75 | 76 | "add += tmp = texture2D( tDiffuse, uv + vec2( -0.993712, -0.111964 ) * sampleSize );", 77 | "if( tmp.b < color.b ) color = tmp;", 78 | 79 | "add += tmp = texture2D( tDiffuse, uv + vec2( -0.707107, 0.707107 ) * sampleSize );", 80 | "if( tmp.b < color.b ) color = tmp;", 81 | 82 | "color = color * vec4( 2.0 ) - ( add / vec4( 8.0 ) );", 83 | "color = color + ( add / vec4( 8.0 ) - color ) * ( vec4( 1.0 ) - vec4( sample_dist * 0.5 ) );", 84 | 85 | "gl_FragColor = vec4( color.rgb * color.rgb * vec3( 0.95 ) + color.rgb, 1.0 );", 86 | 87 | "}" 88 | 89 | 90 | ].join("\n") 91 | }; 92 | -------------------------------------------------------------------------------- /libs/shaders/FresnelShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Based on Nvidia Cg tutorial 5 | */ 6 | 7 | THREE.FresnelShader = { 8 | 9 | uniforms: { 10 | 11 | "mRefractionRatio": { type: "f", value: 1.02 }, 12 | "mFresnelBias": { type: "f", value: 0.1 }, 13 | "mFresnelPower": { type: "f", value: 2.0 }, 14 | "mFresnelScale": { type: "f", value: 1.0 }, 15 | "tCube": { type: "t", value: null } 16 | 17 | }, 18 | 19 | vertexShader: [ 20 | 21 | "uniform float mRefractionRatio;", 22 | "uniform float mFresnelBias;", 23 | "uniform float mFresnelScale;", 24 | "uniform float mFresnelPower;", 25 | 26 | "varying vec3 vReflect;", 27 | "varying vec3 vRefract[3];", 28 | "varying float vReflectionFactor;", 29 | 30 | "void main() {", 31 | 32 | "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", 33 | "vec4 worldPosition = modelMatrix * vec4( position, 1.0 );", 34 | 35 | "vec3 worldNormal = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );", 36 | 37 | "vec3 I = worldPosition.xyz - cameraPosition;", 38 | 39 | "vReflect = reflect( I, worldNormal );", 40 | "vRefract[0] = refract( normalize( I ), worldNormal, mRefractionRatio );", 41 | "vRefract[1] = refract( normalize( I ), worldNormal, mRefractionRatio * 0.99 );", 42 | "vRefract[2] = refract( normalize( I ), worldNormal, mRefractionRatio * 0.98 );", 43 | "vReflectionFactor = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( I ), worldNormal ), mFresnelPower );", 44 | 45 | "gl_Position = projectionMatrix * mvPosition;", 46 | 47 | "}" 48 | 49 | ].join("\n"), 50 | 51 | fragmentShader: [ 52 | 53 | "uniform samplerCube tCube;", 54 | 55 | "varying vec3 vReflect;", 56 | "varying vec3 vRefract[3];", 57 | "varying float vReflectionFactor;", 58 | 59 | "void main() {", 60 | 61 | "vec4 reflectedColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );", 62 | "vec4 refractedColor = vec4( 1.0 );", 63 | 64 | "refractedColor.r = textureCube( tCube, vec3( -vRefract[0].x, vRefract[0].yz ) ).r;", 65 | "refractedColor.g = textureCube( tCube, vec3( -vRefract[1].x, vRefract[1].yz ) ).g;", 66 | "refractedColor.b = textureCube( tCube, vec3( -vRefract[2].x, vRefract[2].yz ) ).b;", 67 | 68 | "gl_FragColor = mix( refractedColor, reflectedColor, clamp( vReflectionFactor, 0.0, 1.0 ) );", 69 | 70 | "}" 71 | 72 | ].join("\n") 73 | 74 | }; 75 | -------------------------------------------------------------------------------- /libs/shaders/HorizontalBlurShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author zz85 / http://www.lab4games.net/zz85/blog 3 | * 4 | * Two pass Gaussian blur filter (horizontal and vertical blur shaders) 5 | * - described in http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/ 6 | * and used in http://www.cake23.de/traveling-wavefronts-lit-up.html 7 | * 8 | * - 9 samples per pass 9 | * - standard deviation 2.7 10 | * - "h" and "v" parameters should be set to "1 / width" and "1 / height" 11 | */ 12 | 13 | THREE.HorizontalBlurShader = { 14 | 15 | uniforms: { 16 | 17 | "tDiffuse": { type: "t", value: null }, 18 | "h": { type: "f", value: 1.0 / 512.0 } 19 | 20 | }, 21 | 22 | vertexShader: [ 23 | 24 | "varying vec2 vUv;", 25 | 26 | "void main() {", 27 | 28 | "vUv = uv;", 29 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 30 | 31 | "}" 32 | 33 | ].join("\n"), 34 | 35 | fragmentShader: [ 36 | 37 | "uniform sampler2D tDiffuse;", 38 | "uniform float h;", 39 | 40 | "varying vec2 vUv;", 41 | 42 | "void main() {", 43 | 44 | "vec4 sum = vec4( 0.0 );", 45 | 46 | "sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * h, vUv.y ) ) * 0.051;", 47 | "sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * h, vUv.y ) ) * 0.0918;", 48 | "sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * h, vUv.y ) ) * 0.12245;", 49 | "sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * h, vUv.y ) ) * 0.1531;", 50 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", 51 | "sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * h, vUv.y ) ) * 0.1531;", 52 | "sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * h, vUv.y ) ) * 0.12245;", 53 | "sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * h, vUv.y ) ) * 0.0918;", 54 | "sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * h, vUv.y ) ) * 0.051;", 55 | 56 | "gl_FragColor = sum;", 57 | 58 | "}" 59 | 60 | ].join("\n") 61 | 62 | }; 63 | -------------------------------------------------------------------------------- /libs/shaders/HorizontalTiltShiftShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Simple fake tilt-shift effect, modulating two pass Gaussian blur (see above) by vertical position 5 | * 6 | * - 9 samples per pass 7 | * - standard deviation 2.7 8 | * - "h" and "v" parameters should be set to "1 / width" and "1 / height" 9 | * - "r" parameter control where "focused" horizontal line lies 10 | */ 11 | 12 | THREE.HorizontalTiltShiftShader = { 13 | 14 | uniforms: { 15 | 16 | "tDiffuse": { type: "t", value: null }, 17 | "h": { type: "f", value: 1.0 / 512.0 }, 18 | "r": { type: "f", value: 0.35 } 19 | 20 | }, 21 | 22 | vertexShader: [ 23 | 24 | "varying vec2 vUv;", 25 | 26 | "void main() {", 27 | 28 | "vUv = uv;", 29 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 30 | 31 | "}" 32 | 33 | ].join("\n"), 34 | 35 | fragmentShader: [ 36 | 37 | "uniform sampler2D tDiffuse;", 38 | "uniform float h;", 39 | "uniform float r;", 40 | 41 | "varying vec2 vUv;", 42 | 43 | "void main() {", 44 | 45 | "vec4 sum = vec4( 0.0 );", 46 | 47 | "float hh = h * abs( r - vUv.y );", 48 | 49 | "sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * hh, vUv.y ) ) * 0.051;", 50 | "sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * hh, vUv.y ) ) * 0.0918;", 51 | "sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * hh, vUv.y ) ) * 0.12245;", 52 | "sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * hh, vUv.y ) ) * 0.1531;", 53 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", 54 | "sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * hh, vUv.y ) ) * 0.1531;", 55 | "sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * hh, vUv.y ) ) * 0.12245;", 56 | "sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * hh, vUv.y ) ) * 0.0918;", 57 | "sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * hh, vUv.y ) ) * 0.051;", 58 | 59 | "gl_FragColor = sum;", 60 | 61 | "}" 62 | 63 | ].join("\n") 64 | 65 | }; 66 | -------------------------------------------------------------------------------- /libs/shaders/HueSaturationShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author tapio / http://tapio.github.com/ 3 | * 4 | * Hue and saturation adjustment 5 | * https://github.com/evanw/glfx.js 6 | * hue: -1 to 1 (-1 is 180 degrees in the negative direction, 0 is no change, etc. 7 | * saturation: -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast) 8 | */ 9 | 10 | THREE.HueSaturationShader = { 11 | 12 | uniforms: { 13 | 14 | "tDiffuse": { type: "t", value: null }, 15 | "hue": { type: "f", value: 0 }, 16 | "saturation": { type: "f", value: 0 } 17 | 18 | }, 19 | 20 | vertexShader: [ 21 | 22 | "varying vec2 vUv;", 23 | 24 | "void main() {", 25 | 26 | "vUv = uv;", 27 | 28 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 29 | 30 | "}" 31 | 32 | ].join("\n"), 33 | 34 | fragmentShader: [ 35 | 36 | "uniform sampler2D tDiffuse;", 37 | "uniform float hue;", 38 | "uniform float saturation;", 39 | 40 | "varying vec2 vUv;", 41 | 42 | "void main() {", 43 | 44 | "gl_FragColor = texture2D( tDiffuse, vUv );", 45 | 46 | // hue 47 | "float angle = hue * 3.14159265;", 48 | "float s = sin(angle), c = cos(angle);", 49 | "vec3 weights = (vec3(2.0 * c, -sqrt(3.0) * s - c, sqrt(3.0) * s - c) + 1.0) / 3.0;", 50 | "float len = length(gl_FragColor.rgb);", 51 | "gl_FragColor.rgb = vec3(", 52 | "dot(gl_FragColor.rgb, weights.xyz),", 53 | "dot(gl_FragColor.rgb, weights.zxy),", 54 | "dot(gl_FragColor.rgb, weights.yzx)", 55 | ");", 56 | 57 | // saturation 58 | "float average = (gl_FragColor.r + gl_FragColor.g + gl_FragColor.b) / 3.0;", 59 | "if (saturation > 0.0) {", 60 | "gl_FragColor.rgb += (average - gl_FragColor.rgb) * (1.0 - 1.0 / (1.001 - saturation));", 61 | "} else {", 62 | "gl_FragColor.rgb += (average - gl_FragColor.rgb) * (-saturation);", 63 | "}", 64 | 65 | "}" 66 | 67 | ].join("\n") 68 | 69 | }; 70 | -------------------------------------------------------------------------------- /libs/shaders/KaleidoShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author felixturner / http://airtight.cc/ 3 | * 4 | * Kaleidoscope Shader 5 | * Radial reflection around center point 6 | * Ported from: http://pixelshaders.com/editor/ 7 | * by Toby Schachman / http://tobyschachman.com/ 8 | * 9 | * sides: number of reflections 10 | * angle: initial angle in radians 11 | */ 12 | 13 | THREE.KaleidoShader = { 14 | 15 | uniforms: { 16 | 17 | "tDiffuse": { type: "t", value: null }, 18 | "sides": { type: "f", value: 6.0 }, 19 | "angle": { type: "f", value: 0.0 } 20 | 21 | }, 22 | 23 | vertexShader: [ 24 | 25 | "varying vec2 vUv;", 26 | 27 | "void main() {", 28 | 29 | "vUv = uv;", 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 float sides;", 40 | "uniform float angle;", 41 | 42 | "varying vec2 vUv;", 43 | 44 | "void main() {", 45 | 46 | "vec2 p = vUv - 0.5;", 47 | "float r = length(p);", 48 | "float a = atan(p.y, p.x) + angle;", 49 | "float tau = 2. * 3.1416 ;", 50 | "a = mod(a, tau/sides);", 51 | "a = abs(a - tau/sides/2.) ;", 52 | "p = r * vec2(cos(a), sin(a));", 53 | "vec4 color = texture2D(tDiffuse, p + 0.5);", 54 | "gl_FragColor = color;", 55 | 56 | "}" 57 | 58 | ].join("\n") 59 | 60 | }; 61 | -------------------------------------------------------------------------------- /libs/shaders/LuminosityShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Luminosity 5 | * http://en.wikipedia.org/wiki/Luminosity 6 | */ 7 | 8 | THREE.LuminosityShader = { 9 | 10 | uniforms: { 11 | 12 | "tDiffuse": { type: "t", value: null } 13 | 14 | }, 15 | 16 | vertexShader: [ 17 | 18 | "varying vec2 vUv;", 19 | 20 | "void main() {", 21 | 22 | "vUv = uv;", 23 | 24 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 25 | 26 | "}" 27 | 28 | ].join("\n"), 29 | 30 | fragmentShader: [ 31 | 32 | "uniform sampler2D tDiffuse;", 33 | 34 | "varying vec2 vUv;", 35 | 36 | "void main() {", 37 | 38 | "vec4 texel = texture2D( tDiffuse, vUv );", 39 | 40 | "vec3 luma = vec3( 0.299, 0.587, 0.114 );", 41 | 42 | "float v = dot( texel.xyz, luma );", 43 | 44 | "gl_FragColor = vec4( v, v, v, texel.w );", 45 | 46 | "}" 47 | 48 | ].join("\n") 49 | 50 | }; 51 | -------------------------------------------------------------------------------- /libs/shaders/MirrorShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author felixturner / http://airtight.cc/ 3 | * 4 | * Mirror Shader 5 | * Copies half the input to the other half 6 | * 7 | * side: side of input to mirror (0 = left, 1 = right, 2 = top, 3 = bottom) 8 | */ 9 | 10 | THREE.MirrorShader = { 11 | 12 | uniforms: { 13 | 14 | "tDiffuse": { type: "t", value: null }, 15 | "side": { type: "i", value: 1 } 16 | 17 | }, 18 | 19 | vertexShader: [ 20 | 21 | "varying vec2 vUv;", 22 | 23 | "void main() {", 24 | 25 | "vUv = uv;", 26 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 27 | 28 | "}" 29 | 30 | ].join("\n"), 31 | 32 | fragmentShader: [ 33 | 34 | "uniform sampler2D tDiffuse;", 35 | "uniform int side;", 36 | 37 | "varying vec2 vUv;", 38 | 39 | "void main() {", 40 | 41 | "vec2 p = vUv;", 42 | "if (side == 0){", 43 | "if (p.x > 0.5) p.x = 1.0 - p.x;", 44 | "}else if (side == 1){", 45 | "if (p.x < 0.5) p.x = 1.0 - p.x;", 46 | "}else if (side == 2){", 47 | "if (p.y < 0.5) p.y = 1.0 - p.y;", 48 | "}else if (side == 3){", 49 | "if (p.y > 0.5) p.y = 1.0 - p.y;", 50 | "} ", 51 | "vec4 color = texture2D(tDiffuse, p);", 52 | "gl_FragColor = color;", 53 | 54 | "}" 55 | 56 | ].join("\n") 57 | 58 | }; 59 | -------------------------------------------------------------------------------- /libs/shaders/NormalMapShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Normal map shader 5 | * - compute normals from heightmap 6 | */ 7 | 8 | THREE.NormalMapShader = { 9 | 10 | uniforms: { 11 | 12 | "heightMap": { type: "t", value: null }, 13 | "resolution": { type: "v2", value: new THREE.Vector2( 512, 512 ) }, 14 | "scale": { type: "v2", value: new THREE.Vector2( 1, 1 ) }, 15 | "height": { type: "f", value: 0.05 } 16 | 17 | }, 18 | 19 | vertexShader: [ 20 | 21 | "varying vec2 vUv;", 22 | 23 | "void main() {", 24 | 25 | "vUv = uv;", 26 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 27 | 28 | "}" 29 | 30 | ].join("\n"), 31 | 32 | fragmentShader: [ 33 | 34 | "uniform float height;", 35 | "uniform vec2 resolution;", 36 | "uniform sampler2D heightMap;", 37 | 38 | "varying vec2 vUv;", 39 | 40 | "void main() {", 41 | 42 | "float val = texture2D( heightMap, vUv ).x;", 43 | 44 | "float valU = texture2D( heightMap, vUv + vec2( 1.0 / resolution.x, 0.0 ) ).x;", 45 | "float valV = texture2D( heightMap, vUv + vec2( 0.0, 1.0 / resolution.y ) ).x;", 46 | 47 | "gl_FragColor = vec4( ( 0.5 * normalize( vec3( val - valU, val - valV, height ) ) + 0.5 ), 1.0 );", 48 | 49 | "}" 50 | 51 | ].join("\n") 52 | 53 | }; 54 | -------------------------------------------------------------------------------- /libs/shaders/RGBShiftShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author felixturner / http://airtight.cc/ 3 | * 4 | * RGB Shift Shader 5 | * Shifts red and blue channels from center in opposite directions 6 | * Ported from http://kriss.cx/tom/2009/05/rgb-shift/ 7 | * by Tom Butterworth / http://kriss.cx/tom/ 8 | * 9 | * amount: shift distance (1 is width of input) 10 | * angle: shift angle in radians 11 | */ 12 | 13 | THREE.RGBShiftShader = { 14 | 15 | uniforms: { 16 | 17 | "tDiffuse": { type: "t", value: null }, 18 | "amount": { type: "f", value: 0.005 }, 19 | "angle": { type: "f", value: 0.0 } 20 | 21 | }, 22 | 23 | vertexShader: [ 24 | 25 | "varying vec2 vUv;", 26 | 27 | "void main() {", 28 | 29 | "vUv = uv;", 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 float amount;", 40 | "uniform float angle;", 41 | 42 | "varying vec2 vUv;", 43 | 44 | "void main() {", 45 | 46 | "vec2 offset = amount * vec2( cos(angle), sin(angle));", 47 | "vec4 cr = texture2D(tDiffuse, vUv + offset);", 48 | "vec4 cga = texture2D(tDiffuse, vUv);", 49 | "vec4 cb = texture2D(tDiffuse, vUv - offset);", 50 | "gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);", 51 | 52 | "}" 53 | 54 | ].join("\n") 55 | 56 | }; 57 | -------------------------------------------------------------------------------- /libs/shaders/SSAOShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Screen-space ambient occlusion shader 5 | * - ported from 6 | * SSAO GLSL shader v1.2 7 | * assembled by Martins Upitis (martinsh) (http://devlog-martinsh.blogspot.com) 8 | * original technique is made by ArKano22 (http://www.gamedev.net/topic/550699-ssao-no-halo-artifacts/) 9 | * - modifications 10 | * - modified to use RGBA packed depth texture (use clear color 1,1,1,1 for depth pass) 11 | * - made fog more compatible with three.js linear fog 12 | * - refactoring and optimizations 13 | */ 14 | 15 | THREE.SSAOShader = { 16 | 17 | uniforms: { 18 | 19 | "tDiffuse": { type: "t", value: null }, 20 | "tDepth": { type: "t", value: null }, 21 | "size": { type: "v2", value: new THREE.Vector2( 512, 512 ) }, 22 | "cameraNear": { type: "f", value: 1 }, 23 | "cameraFar": { type: "f", value: 100 }, 24 | "fogNear": { type: "f", value: 5 }, 25 | "fogFar": { type: "f", value: 100 }, 26 | "fogEnabled": { type: "i", value: 0 }, 27 | "onlyAO": { type: "i", value: 0 }, 28 | "aoClamp": { type: "f", value: 0.3 }, 29 | "lumInfluence": { type: "f", value: 0.9 } 30 | 31 | }, 32 | 33 | vertexShader: [ 34 | 35 | "varying vec2 vUv;", 36 | 37 | "void main() {", 38 | 39 | "vUv = uv;", 40 | 41 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 42 | 43 | "}" 44 | 45 | ].join("\n"), 46 | 47 | fragmentShader: [ 48 | 49 | "uniform float cameraNear;", 50 | "uniform float cameraFar;", 51 | 52 | "uniform float fogNear;", 53 | "uniform float fogFar;", 54 | 55 | "uniform bool fogEnabled;", // attenuate AO with linear fog 56 | "uniform bool onlyAO;", // use only ambient occlusion pass? 57 | 58 | "uniform vec2 size;", // texture width, height 59 | "uniform float aoClamp;", // depth clamp - reduces haloing at screen edges 60 | 61 | "uniform float lumInfluence;", // how much luminance affects occlusion 62 | 63 | "uniform sampler2D tDiffuse;", 64 | "uniform sampler2D tDepth;", 65 | 66 | "varying vec2 vUv;", 67 | 68 | // "#define PI 3.14159265", 69 | "#define DL 2.399963229728653", // PI * ( 3.0 - sqrt( 5.0 ) ) 70 | "#define EULER 2.718281828459045", 71 | 72 | // helpers 73 | 74 | "float width = size.x;", // texture width 75 | "float height = size.y;", // texture height 76 | 77 | "float cameraFarPlusNear = cameraFar + cameraNear;", 78 | "float cameraFarMinusNear = cameraFar - cameraNear;", 79 | "float cameraCoef = 2.0 * cameraNear;", 80 | 81 | // user variables 82 | 83 | "const int samples = 8;", // ao sample count 84 | "const float radius = 5.0;", // ao radius 85 | 86 | "const bool useNoise = false;", // use noise instead of pattern for sample dithering 87 | "const float noiseAmount = 0.0003;", // dithering amount 88 | 89 | "const float diffArea = 0.4;", // self-shadowing reduction 90 | "const float gDisplace = 0.4;", // gauss bell center 91 | 92 | "const vec3 onlyAOColor = vec3( 1.0, 0.7, 0.5 );", 93 | // "const vec3 onlyAOColor = vec3( 1.0, 1.0, 1.0 );", 94 | 95 | 96 | // RGBA depth 97 | 98 | "float unpackDepth( const in vec4 rgba_depth ) {", 99 | 100 | "const vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );", 101 | "float depth = dot( rgba_depth, bit_shift );", 102 | "return depth;", 103 | 104 | "}", 105 | 106 | // generating noise / pattern texture for dithering 107 | 108 | "vec2 rand( const vec2 coord ) {", 109 | 110 | "vec2 noise;", 111 | 112 | "if ( useNoise ) {", 113 | 114 | "float nx = dot ( coord, vec2( 12.9898, 78.233 ) );", 115 | "float ny = dot ( coord, vec2( 12.9898, 78.233 ) * 2.0 );", 116 | 117 | "noise = clamp( fract ( 43758.5453 * sin( vec2( nx, ny ) ) ), 0.0, 1.0 );", 118 | 119 | "} else {", 120 | 121 | "float ff = fract( 1.0 - coord.s * ( width / 2.0 ) );", 122 | "float gg = fract( coord.t * ( height / 2.0 ) );", 123 | 124 | "noise = vec2( 0.25, 0.75 ) * vec2( ff ) + vec2( 0.75, 0.25 ) * gg;", 125 | 126 | "}", 127 | 128 | "return ( noise * 2.0 - 1.0 ) * noiseAmount;", 129 | 130 | "}", 131 | 132 | "float doFog() {", 133 | 134 | "float zdepth = unpackDepth( texture2D( tDepth, vUv ) );", 135 | "float depth = -cameraFar * cameraNear / ( zdepth * cameraFarMinusNear - cameraFar );", 136 | 137 | "return smoothstep( fogNear, fogFar, depth );", 138 | 139 | "}", 140 | 141 | "float readDepth( const in vec2 coord ) {", 142 | 143 | // "return ( 2.0 * cameraNear ) / ( cameraFar + cameraNear - unpackDepth( texture2D( tDepth, coord ) ) * ( cameraFar - cameraNear ) );", 144 | "return cameraCoef / ( cameraFarPlusNear - unpackDepth( texture2D( tDepth, coord ) ) * cameraFarMinusNear );", 145 | 146 | 147 | "}", 148 | 149 | "float compareDepths( const in float depth1, const in float depth2, inout int far ) {", 150 | 151 | "float garea = 2.0;", // gauss bell width 152 | "float diff = ( depth1 - depth2 ) * 100.0;", // depth difference (0-100) 153 | 154 | // reduce left bell width to avoid self-shadowing 155 | 156 | "if ( diff < gDisplace ) {", 157 | 158 | "garea = diffArea;", 159 | 160 | "} else {", 161 | 162 | "far = 1;", 163 | 164 | "}", 165 | 166 | "float dd = diff - gDisplace;", 167 | "float gauss = pow( EULER, -2.0 * dd * dd / ( garea * garea ) );", 168 | "return gauss;", 169 | 170 | "}", 171 | 172 | "float calcAO( float depth, float dw, float dh ) {", 173 | 174 | "float dd = radius - depth * radius;", 175 | "vec2 vv = vec2( dw, dh );", 176 | 177 | "vec2 coord1 = vUv + dd * vv;", 178 | "vec2 coord2 = vUv - dd * vv;", 179 | 180 | "float temp1 = 0.0;", 181 | "float temp2 = 0.0;", 182 | 183 | "int far = 0;", 184 | "temp1 = compareDepths( depth, readDepth( coord1 ), far );", 185 | 186 | // DEPTH EXTRAPOLATION 187 | 188 | "if ( far > 0 ) {", 189 | 190 | "temp2 = compareDepths( readDepth( coord2 ), depth, far );", 191 | "temp1 += ( 1.0 - temp1 ) * temp2;", 192 | 193 | "}", 194 | 195 | "return temp1;", 196 | 197 | "}", 198 | 199 | "void main() {", 200 | 201 | "vec2 noise = rand( vUv );", 202 | "float depth = readDepth( vUv );", 203 | 204 | "float tt = clamp( depth, aoClamp, 1.0 );", 205 | 206 | "float w = ( 1.0 / width ) / tt + ( noise.x * ( 1.0 - noise.x ) );", 207 | "float h = ( 1.0 / height ) / tt + ( noise.y * ( 1.0 - noise.y ) );", 208 | 209 | "float pw;", 210 | "float ph;", 211 | 212 | "float ao;", 213 | 214 | "float dz = 1.0 / float( samples );", 215 | "float z = 1.0 - dz / 2.0;", 216 | "float l = 0.0;", 217 | 218 | "for ( int i = 0; i <= samples; i ++ ) {", 219 | 220 | "float r = sqrt( 1.0 - z );", 221 | 222 | "pw = cos( l ) * r;", 223 | "ph = sin( l ) * r;", 224 | "ao += calcAO( depth, pw * w, ph * h );", 225 | "z = z - dz;", 226 | "l = l + DL;", 227 | 228 | "}", 229 | 230 | "ao /= float( samples );", 231 | "ao = 1.0 - ao;", 232 | 233 | "if ( fogEnabled ) {", 234 | 235 | "ao = mix( ao, 1.0, doFog() );", 236 | 237 | "}", 238 | 239 | "vec3 color = texture2D( tDiffuse, vUv ).rgb;", 240 | 241 | "vec3 lumcoeff = vec3( 0.299, 0.587, 0.114 );", 242 | "float lum = dot( color.rgb, lumcoeff );", 243 | "vec3 luminance = vec3( lum );", 244 | 245 | "vec3 final = vec3( color * mix( vec3( ao ), vec3( 1.0 ), luminance * lumInfluence ) );", // mix( color * ao, white, luminance ) 246 | 247 | "if ( onlyAO ) {", 248 | 249 | "final = onlyAOColor * vec3( mix( vec3( ao ), vec3( 1.0 ), luminance * lumInfluence ) );", // ambient occlusion only 250 | 251 | "}", 252 | 253 | "gl_FragColor = vec4( final, 1.0 );", 254 | 255 | "}" 256 | 257 | ].join("\n") 258 | 259 | }; 260 | -------------------------------------------------------------------------------- /libs/shaders/SepiaShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Sepia tone shader 5 | * based on glfx.js sepia shader 6 | * https://github.com/evanw/glfx.js 7 | */ 8 | 9 | THREE.SepiaShader = { 10 | 11 | uniforms: { 12 | 13 | "tDiffuse": { type: "t", value: null }, 14 | "amount": { type: "f", value: 1.0 } 15 | 16 | }, 17 | 18 | vertexShader: [ 19 | 20 | "varying vec2 vUv;", 21 | 22 | "void main() {", 23 | 24 | "vUv = uv;", 25 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 26 | 27 | "}" 28 | 29 | ].join("\n"), 30 | 31 | fragmentShader: [ 32 | 33 | "uniform float amount;", 34 | 35 | "uniform sampler2D tDiffuse;", 36 | 37 | "varying vec2 vUv;", 38 | 39 | "void main() {", 40 | 41 | "vec4 color = texture2D( tDiffuse, vUv );", 42 | "vec3 c = color.rgb;", 43 | 44 | "color.r = dot( c, vec3( 1.0 - 0.607 * amount, 0.769 * amount, 0.189 * amount ) );", 45 | "color.g = dot( c, vec3( 0.349 * amount, 1.0 - 0.314 * amount, 0.168 * amount ) );", 46 | "color.b = dot( c, vec3( 0.272 * amount, 0.534 * amount, 1.0 - 0.869 * amount ) );", 47 | 48 | "gl_FragColor = vec4( min( vec3( 1.0 ), color.rgb ), color.a );", 49 | 50 | "}" 51 | 52 | ].join("\n") 53 | 54 | }; 55 | -------------------------------------------------------------------------------- /libs/shaders/TriangleBlurShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author zz85 / http://www.lab4games.net/zz85/blog 3 | * 4 | * Triangle blur shader 5 | * based on glfx.js triangle blur shader 6 | * https://github.com/evanw/glfx.js 7 | * 8 | * A basic blur filter, which convolves the image with a 9 | * pyramid filter. The pyramid filter is separable and is applied as two 10 | * perpendicular triangle filters. 11 | */ 12 | 13 | THREE.TriangleBlurShader = { 14 | 15 | uniforms : { 16 | 17 | "texture": { type: "t", value: null }, 18 | "delta": { type: "v2", value:new THREE.Vector2( 1, 1 ) } 19 | 20 | }, 21 | 22 | vertexShader: [ 23 | 24 | "varying vec2 vUv;", 25 | 26 | "void main() {", 27 | 28 | "vUv = uv;", 29 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 30 | 31 | "}" 32 | 33 | ].join("\n"), 34 | 35 | fragmentShader: [ 36 | 37 | "#define ITERATIONS 10.0", 38 | 39 | "uniform sampler2D texture;", 40 | "uniform vec2 delta;", 41 | 42 | "varying vec2 vUv;", 43 | 44 | "float random( vec3 scale, float seed ) {", 45 | 46 | // use the fragment position for a different seed per-pixel 47 | 48 | "return fract( sin( dot( gl_FragCoord.xyz + seed, scale ) ) * 43758.5453 + seed );", 49 | 50 | "}", 51 | 52 | "void main() {", 53 | 54 | "vec4 color = vec4( 0.0 );", 55 | 56 | "float total = 0.0;", 57 | 58 | // randomize the lookup values to hide the fixed number of samples 59 | 60 | "float offset = random( vec3( 12.9898, 78.233, 151.7182 ), 0.0 );", 61 | 62 | "for ( float t = -ITERATIONS; t <= ITERATIONS; t ++ ) {", 63 | 64 | "float percent = ( t + offset - 0.5 ) / ITERATIONS;", 65 | "float weight = 1.0 - abs( percent );", 66 | 67 | "color += texture2D( texture, vUv + delta * percent ) * weight;", 68 | "total += weight;", 69 | 70 | "}", 71 | 72 | "gl_FragColor = color / total;", 73 | 74 | "}" 75 | 76 | ].join("\n") 77 | 78 | }; 79 | -------------------------------------------------------------------------------- /libs/shaders/UnpackDepthRGBAShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Unpack RGBA depth shader 5 | * - show RGBA encoded depth as monochrome color 6 | */ 7 | 8 | THREE.UnpackDepthRGBAShader = { 9 | 10 | uniforms: { 11 | 12 | "tDiffuse": { type: "t", value: null }, 13 | "opacity": { type: "f", value: 1.0 } 14 | 15 | }, 16 | 17 | vertexShader: [ 18 | 19 | "varying vec2 vUv;", 20 | 21 | "void main() {", 22 | 23 | "vUv = uv;", 24 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 25 | 26 | "}" 27 | 28 | ].join("\n"), 29 | 30 | fragmentShader: [ 31 | 32 | "uniform float opacity;", 33 | 34 | "uniform sampler2D tDiffuse;", 35 | 36 | "varying vec2 vUv;", 37 | 38 | // RGBA depth 39 | 40 | "float unpackDepth( const in vec4 rgba_depth ) {", 41 | 42 | "const vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );", 43 | "float depth = dot( rgba_depth, bit_shift );", 44 | "return depth;", 45 | 46 | "}", 47 | 48 | "void main() {", 49 | 50 | "float depth = 1.0 - unpackDepth( texture2D( tDiffuse, vUv ) );", 51 | "gl_FragColor = opacity * vec4( vec3( depth ), 1.0 );", 52 | 53 | "}" 54 | 55 | ].join("\n") 56 | 57 | }; 58 | -------------------------------------------------------------------------------- /libs/shaders/VerticalBlurShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author zz85 / http://www.lab4games.net/zz85/blog 3 | * 4 | * Two pass Gaussian blur filter (horizontal and vertical blur shaders) 5 | * - described in http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/ 6 | * and used in http://www.cake23.de/traveling-wavefronts-lit-up.html 7 | * 8 | * - 9 samples per pass 9 | * - standard deviation 2.7 10 | * - "h" and "v" parameters should be set to "1 / width" and "1 / height" 11 | */ 12 | 13 | THREE.VerticalBlurShader = { 14 | 15 | uniforms: { 16 | 17 | "tDiffuse": { type: "t", value: null }, 18 | "v": { type: "f", value: 1.0 / 512.0 } 19 | 20 | }, 21 | 22 | vertexShader: [ 23 | 24 | "varying vec2 vUv;", 25 | 26 | "void main() {", 27 | 28 | "vUv = uv;", 29 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 30 | 31 | "}" 32 | 33 | ].join("\n"), 34 | 35 | fragmentShader: [ 36 | 37 | "uniform sampler2D tDiffuse;", 38 | "uniform float v;", 39 | 40 | "varying vec2 vUv;", 41 | 42 | "void main() {", 43 | 44 | "vec4 sum = vec4( 0.0 );", 45 | 46 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * v ) ) * 0.051;", 47 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * v ) ) * 0.0918;", 48 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * v ) ) * 0.12245;", 49 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * v ) ) * 0.1531;", 50 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", 51 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * v ) ) * 0.1531;", 52 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * v ) ) * 0.12245;", 53 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * v ) ) * 0.0918;", 54 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * v ) ) * 0.051;", 55 | 56 | "gl_FragColor = sum;", 57 | 58 | "}" 59 | 60 | ].join("\n") 61 | 62 | }; 63 | -------------------------------------------------------------------------------- /libs/shaders/VerticalTiltShiftShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Simple fake tilt-shift effect, modulating two pass Gaussian blur (see above) by vertical position 5 | * 6 | * - 9 samples per pass 7 | * - standard deviation 2.7 8 | * - "h" and "v" parameters should be set to "1 / width" and "1 / height" 9 | * - "r" parameter control where "focused" horizontal line lies 10 | */ 11 | 12 | THREE.VerticalTiltShiftShader = { 13 | 14 | uniforms: { 15 | 16 | "tDiffuse": { type: "t", value: null }, 17 | "v": { type: "f", value: 1.0 / 512.0 }, 18 | "r": { type: "f", value: 0.35 } 19 | 20 | }, 21 | 22 | vertexShader: [ 23 | 24 | "varying vec2 vUv;", 25 | 26 | "void main() {", 27 | 28 | "vUv = uv;", 29 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 30 | 31 | "}" 32 | 33 | ].join("\n"), 34 | 35 | fragmentShader: [ 36 | 37 | "uniform sampler2D tDiffuse;", 38 | "uniform float v;", 39 | "uniform float r;", 40 | 41 | "varying vec2 vUv;", 42 | 43 | "void main() {", 44 | 45 | "vec4 sum = vec4( 0.0 );", 46 | 47 | "float vv = v * abs( r - vUv.y );", 48 | 49 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * vv ) ) * 0.051;", 50 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * vv ) ) * 0.0918;", 51 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * vv ) ) * 0.12245;", 52 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * vv ) ) * 0.1531;", 53 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", 54 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * vv ) ) * 0.1531;", 55 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * vv ) ) * 0.12245;", 56 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * vv ) ) * 0.0918;", 57 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * vv ) ) * 0.051;", 58 | 59 | "gl_FragColor = sum;", 60 | 61 | "}" 62 | 63 | ].join("\n") 64 | 65 | }; 66 | -------------------------------------------------------------------------------- /libs/shaders/VignetteShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Vignette shader 5 | * based on PaintEffect postprocess from ro.me 6 | * http://code.google.com/p/3-dreams-of-black/source/browse/deploy/js/effects/PaintEffect.js 7 | */ 8 | 9 | THREE.VignetteShader = { 10 | 11 | uniforms: { 12 | 13 | "tDiffuse": { type: "t", value: null }, 14 | "offset": { type: "f", value: 1.0 }, 15 | "darkness": { type: "f", value: 1.0 } 16 | 17 | }, 18 | 19 | vertexShader: [ 20 | 21 | "varying vec2 vUv;", 22 | 23 | "void main() {", 24 | 25 | "vUv = uv;", 26 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 27 | 28 | "}" 29 | 30 | ].join("\n"), 31 | 32 | fragmentShader: [ 33 | 34 | "uniform float offset;", 35 | "uniform float darkness;", 36 | 37 | "uniform sampler2D tDiffuse;", 38 | 39 | "varying vec2 vUv;", 40 | 41 | "void main() {", 42 | 43 | // Eskil's vignette 44 | 45 | "vec4 texel = texture2D( tDiffuse, vUv );", 46 | "vec2 uv = ( vUv - vec2( 0.5 ) ) * vec2( offset );", 47 | "gl_FragColor = vec4( mix( texel.rgb, vec3( 1.0 - darkness ), dot( uv, uv ) ), texel.a );", 48 | 49 | /* 50 | // alternative version from glfx.js 51 | // this one makes more "dusty" look (as opposed to "burned") 52 | 53 | "vec4 color = texture2D( tDiffuse, vUv );", 54 | "float dist = distance( vUv, vec2( 0.5 ) );", 55 | "color.rgb *= smoothstep( 0.8, offset * 0.799, dist *( darkness + offset ) );", 56 | "gl_FragColor = color;", 57 | */ 58 | 59 | "}" 60 | 61 | ].join("\n") 62 | 63 | }; 64 | -------------------------------------------------------------------------------- /libs/sketch.js: -------------------------------------------------------------------------------- 1 | var __slice = Array.prototype.slice; 2 | (function($) { 3 | var Sketch; 4 | $.fn.sketch = function() { 5 | var args, key, sketch; 6 | key = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; 7 | if (this.length > 1) { 8 | $.error('Sketch.js can only be called on one element at a time.'); 9 | } 10 | sketch = this.data('sketch'); 11 | if (typeof key === 'string' && sketch) { 12 | if (sketch[key]) { 13 | if (typeof sketch[key] === 'function') { 14 | return sketch[key].apply(sketch, args); 15 | } else if (args.length === 0) { 16 | return sketch[key]; 17 | } else if (args.length === 1) { 18 | return sketch[key] = args[0]; 19 | } 20 | } else { 21 | return $.error('Sketch.js did not recognize the given command.'); 22 | } 23 | } else if (sketch) { 24 | return sketch; 25 | } else { 26 | this.data('sketch', new Sketch(this.get(0), key)); 27 | return this; 28 | } 29 | }; 30 | Sketch = (function() { 31 | function Sketch(el, opts) { 32 | this.el = el; 33 | this.canvas = $(el); 34 | this.context = el.getContext('2d'); 35 | this.options = $.extend({ 36 | toolLinks: true, 37 | defaultTool: 'marker', 38 | defaultColor: '#000000', 39 | defaultSize: 5 40 | }, opts); 41 | this.painting = false; 42 | this.color = this.options.defaultColor; 43 | this.size = this.options.defaultSize; 44 | this.tool = this.options.defaultTool; 45 | this.actions = []; 46 | this.action = []; 47 | this.canvas.bind('click mousedown mouseup mousemove mouseleave mouseout touchstart touchmove touchend touchcancel', this.onEvent); 48 | if (this.options.toolLinks) { 49 | $('body').delegate("a[href=\"#" + (this.canvas.attr('id')) + "\"]", 'click', function(e) { 50 | var $canvas, $this, key, sketch, _i, _len, _ref; 51 | $this = $(this); 52 | $canvas = $($this.attr('href')); 53 | sketch = $canvas.data('sketch'); 54 | _ref = ['color', 'size', 'tool']; 55 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { 56 | key = _ref[_i]; 57 | if ($this.attr("data-" + key)) { 58 | sketch.set(key, $(this).attr("data-" + key)); 59 | } 60 | } 61 | if ($(this).attr('data-download')) { 62 | sketch.download($(this).attr('data-download')); 63 | } 64 | return false; 65 | }); 66 | } 67 | } 68 | Sketch.prototype.download = function(format) { 69 | var mime; 70 | format || (format = "png"); 71 | if (format === "jpg") { 72 | format = "jpeg"; 73 | } 74 | mime = "image/" + format; 75 | return window.open(this.el.toDataURL(mime)); 76 | }; 77 | Sketch.prototype.set = function(key, value) { 78 | this[key] = value; 79 | return this.canvas.trigger("sketch.change" + key, value); 80 | }; 81 | Sketch.prototype.startPainting = function() { 82 | this.painting = true; 83 | return this.action = { 84 | tool: this.tool, 85 | color: this.color, 86 | size: parseFloat(this.size), 87 | events: [] 88 | }; 89 | }; 90 | Sketch.prototype.stopPainting = function() { 91 | if (this.action) { 92 | this.actions.push(this.action); 93 | } 94 | this.painting = false; 95 | this.action = null; 96 | return this.redraw(); 97 | }; 98 | Sketch.prototype.onEvent = function(e) { 99 | if (e.originalEvent && e.originalEvent.targetTouches) { 100 | e.pageX = e.originalEvent.targetTouches[0].pageX; 101 | e.pageY = e.originalEvent.targetTouches[0].pageY; 102 | } 103 | $.sketch.tools[$(this).data('sketch').tool].onEvent.call($(this).data('sketch'), e); 104 | e.preventDefault(); 105 | return false; 106 | }; 107 | Sketch.prototype.redraw = function() { 108 | var sketch; 109 | // this.el.width = this.canvas.width(); 110 | this.context = this.el.getContext('2d'); 111 | sketch = this; 112 | $.each(this.actions, function() { 113 | if (this.tool) { 114 | return $.sketch.tools[this.tool].draw.call(sketch, this); 115 | } 116 | }); 117 | if (this.painting && this.action) { 118 | return $.sketch.tools[this.action.tool].draw.call(sketch, this.action); 119 | } 120 | }; 121 | return Sketch; 122 | })(); 123 | $.sketch = { 124 | tools: {} 125 | }; 126 | $.sketch.tools.marker = { 127 | onEvent: function(e) { 128 | switch (e.type) { 129 | case 'mousedown': 130 | case 'touchstart': 131 | this.startPainting(); 132 | break; 133 | case 'mouseup': 134 | case 'mouseout': 135 | case 'mouseleave': 136 | case 'touchend': 137 | case 'touchcancel': 138 | this.stopPainting(); 139 | } 140 | if (this.painting) { 141 | this.action.events.push({ 142 | x: e.pageX - this.canvas.offset().left, 143 | y: e.pageY - this.canvas.offset().top, 144 | event: e.type 145 | }); 146 | return this.redraw(); 147 | } 148 | }, 149 | draw: function(action) { 150 | var event, previous, _i, _len, _ref; 151 | this.context.lineJoin = "round"; 152 | this.context.lineCap = "round"; 153 | this.context.beginPath(); 154 | this.context.moveTo(action.events[0].x, action.events[0].y); 155 | _ref = action.events; 156 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { 157 | event = _ref[_i]; 158 | this.context.lineTo(event.x, event.y); 159 | previous = event; 160 | } 161 | this.context.strokeStyle = action.color; 162 | this.context.lineWidth = action.size; 163 | return this.context.stroke(); 164 | } 165 | }; 166 | return $.sketch.tools.eraser = { 167 | onEvent: function(e) { 168 | return $.sketch.tools.marker.onEvent.call(this, e); 169 | }, 170 | draw: function(action) { 171 | var oldcomposite; 172 | oldcomposite = this.context.globalCompositeOperation; 173 | this.context.globalCompositeOperation = "copy"; 174 | action.color = "rgba(0,0,0,0)"; 175 | $.sketch.tools.marker.draw.call(this, action); 176 | return this.context.globalCompositeOperation = oldcomposite; 177 | } 178 | }; 179 | })(jQuery); -------------------------------------------------------------------------------- /libs/spin.js: -------------------------------------------------------------------------------- 1 | (function(t,e){if(typeof exports=="object")module.exports=e();else if(typeof define=="function"&&define.amd)define(e);else t.Spinner=e()})(this,function(){"use strict";var t=["webkit","Moz","ms","O"],e={},i;function o(t,e){var i=document.createElement(t||"div"),o;for(o in e)i[o]=e[o];return i}function n(t){for(var e=1,i=arguments.length;e>1):parseInt(n.left,10)+s)+"px",top:(n.top=="auto"?l.y-a.y+(t.offsetHeight>>1):parseInt(n.top,10)+s)+"px"})}r.setAttribute("role","progressbar");e.lines(r,e.opts);if(!i){var d=0,p=(n.lines-1)*(1-n.direction)/2,c,h=n.fps,m=h/n.speed,y=(1-n.opacity)/(m*n.trail/100),g=m/n.lines;(function v(){d++;for(var t=0;t>1)+"px"})}for(;r',e)}r.addRule(".spin-vml","behavior:url(#default#VML)");c.prototype.lines=function(e,i){var o=i.length+i.width,r=2*o;function s(){return f(t("group",{coordsize:r+" "+r,coordorigin:-o+" "+-o}),{width:r,height:r})}var a=-(i.width+i.length)*2+"px",l=f(s(),{position:"absolute",top:a,left:a}),u;function p(e,r,a){n(l,n(f(s(),{rotation:360/i.lines*e+"deg",left:~~r}),n(f(t("roundrect",{arcsize:i.corners}),{width:o,height:i.width,left:i.radius,top:-i.width>>1,filter:a}),t("fill",{color:d(i.color,e),opacity:i.opacity}),t("stroke",{opacity:0}))))}if(i.shadow)for(u=1;u<=i.lines;u++)p(u,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(u=1;u<=i.lines;u++)p(u);return n(e,l)};c.prototype.opacity=function(t,e,i,o){var n=t.firstChild;o=o.shadow&&o.lines||0;if(n&&e+o prevTime + 1000 ) { 118 | 119 | fps = Math.round( ( frames * 1000 ) / ( time - prevTime ) ); 120 | fpsMin = Math.min( fpsMin, fps ); 121 | fpsMax = Math.max( fpsMax, fps ); 122 | 123 | fpsText.textContent = fps + ' FPS (' + fpsMin + '-' + fpsMax + ')'; 124 | updateGraph( fpsGraph, Math.min( 30, 30 - ( fps / 100 ) * 30 ) ); 125 | 126 | prevTime = time; 127 | frames = 0; 128 | 129 | } 130 | 131 | return time; 132 | 133 | }, 134 | 135 | update: function () { 136 | 137 | startTime = this.end(); 138 | 139 | } 140 | 141 | } 142 | 143 | }; 144 | -------------------------------------------------------------------------------- /libs/tween.min.js: -------------------------------------------------------------------------------- 1 | // tween.js - http://github.com/sole/tween.js 2 | 'use strict';var TWEEN=TWEEN||function(){var a=[];return{REVISION:"10",getAll:function(){return a},removeAll:function(){a=[]},add:function(c){a.push(c)},remove:function(c){c=a.indexOf(c);-1!==c&&a.splice(c,1)},update:function(c){if(0===a.length)return!1;for(var b=0,d=a.length,c=void 0!==c?c:void 0!==window.performance&&void 0!==window.performance.now?window.performance.now():Date.now();b(a*=2)?0.5*a*a:-0.5*(--a*(a-2)-1)}},Cubic:{In:function(a){return a*a*a},Out:function(a){return--a*a*a+1},InOut:function(a){return 1>(a*=2)?0.5*a*a*a:0.5*((a-=2)*a*a+2)}},Quartic:{In:function(a){return a*a*a*a},Out:function(a){return 1- --a*a*a*a},InOut:function(a){return 1>(a*=2)?0.5*a*a*a*a:-0.5*((a-=2)*a*a*a-2)}},Quintic:{In:function(a){return a*a*a* 7 | a*a},Out:function(a){return--a*a*a*a*a+1},InOut:function(a){return 1>(a*=2)?0.5*a*a*a*a*a:0.5*((a-=2)*a*a*a*a+2)}},Sinusoidal:{In:function(a){return 1-Math.cos(a*Math.PI/2)},Out:function(a){return Math.sin(a*Math.PI/2)},InOut:function(a){return 0.5*(1-Math.cos(Math.PI*a))}},Exponential:{In:function(a){return 0===a?0:Math.pow(1024,a-1)},Out:function(a){return 1===a?1:1-Math.pow(2,-10*a)},InOut:function(a){return 0===a?0:1===a?1:1>(a*=2)?0.5*Math.pow(1024,a-1):0.5*(-Math.pow(2,-10*(a-1))+2)}},Circular:{In:function(a){return 1- 8 | Math.sqrt(1-a*a)},Out:function(a){return Math.sqrt(1- --a*a)},InOut:function(a){return 1>(a*=2)?-0.5*(Math.sqrt(1-a*a)-1):0.5*(Math.sqrt(1-(a-=2)*a)+1)}},Elastic:{In:function(a){var c,b=0.1;if(0===a)return 0;if(1===a)return 1;!b||1>b?(b=1,c=0.1):c=0.4*Math.asin(1/b)/(2*Math.PI);return-(b*Math.pow(2,10*(a-=1))*Math.sin((a-c)*2*Math.PI/0.4))},Out:function(a){var c,b=0.1;if(0===a)return 0;if(1===a)return 1;!b||1>b?(b=1,c=0.1):c=0.4*Math.asin(1/b)/(2*Math.PI);return b*Math.pow(2,-10*a)*Math.sin((a-c)* 9 | 2*Math.PI/0.4)+1},InOut:function(a){var c,b=0.1;if(0===a)return 0;if(1===a)return 1;!b||1>b?(b=1,c=0.1):c=0.4*Math.asin(1/b)/(2*Math.PI);return 1>(a*=2)?-0.5*b*Math.pow(2,10*(a-=1))*Math.sin((a-c)*2*Math.PI/0.4):0.5*b*Math.pow(2,-10*(a-=1))*Math.sin((a-c)*2*Math.PI/0.4)+1}},Back:{In:function(a){return a*a*(2.70158*a-1.70158)},Out:function(a){return--a*a*(2.70158*a+1.70158)+1},InOut:function(a){return 1>(a*=2)?0.5*a*a*(3.5949095*a-2.5949095):0.5*((a-=2)*a*(3.5949095*a+2.5949095)+2)}},Bounce:{In:function(a){return 1- 10 | TWEEN.Easing.Bounce.Out(1-a)},Out:function(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+0.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+0.9375:7.5625*(a-=2.625/2.75)*a+0.984375},InOut:function(a){return 0.5>a?0.5*TWEEN.Easing.Bounce.In(2*a):0.5*TWEEN.Easing.Bounce.Out(2*a-1)+0.5}}}; 11 | TWEEN.Interpolation={Linear:function(a,c){var b=a.length-1,d=b*c,e=Math.floor(d),g=TWEEN.Interpolation.Utils.Linear;return 0>c?g(a[0],a[1],d):1b?b:e+1],d-e)},Bezier:function(a,c){var b=0,d=a.length-1,e=Math.pow,g=TWEEN.Interpolation.Utils.Bernstein,i;for(i=0;i<=d;i++)b+=e(1-c,d-i)*e(c,i)*a[i]*g(d,i);return b},CatmullRom:function(a,c){var b=a.length-1,d=b*c,e=Math.floor(d),g=TWEEN.Interpolation.Utils.CatmullRom;return a[0]===a[b]?(0>c&&(e=Math.floor(d=b*(1+c))),g(a[(e- 12 | 1+b)%b],a[e],a[(e+1)%b],a[(e+2)%b],d-e)):0>c?a[0]-(g(a[0],a[0],a[1],a[1],-d)-a[0]):1 2 | 3 | 4 | 5 | 6 | Moon Buggy 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 21 | 22 |
23 | 35 | 36 | -------------------------------------------------------------------------------- /moon-buggy/resources/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/moon-buggy/resources/background.png -------------------------------------------------------------------------------- /moon-buggy/resources/body.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/moon-buggy/resources/body.png -------------------------------------------------------------------------------- /moon-buggy/resources/earth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/moon-buggy/resources/earth.png -------------------------------------------------------------------------------- /moon-buggy/resources/giraffe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/moon-buggy/resources/giraffe.png -------------------------------------------------------------------------------- /moon-buggy/resources/lion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/moon-buggy/resources/lion.png -------------------------------------------------------------------------------- /moon-buggy/resources/penguin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/moon-buggy/resources/penguin.png -------------------------------------------------------------------------------- /moon-buggy/resources/rainbow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/moon-buggy/resources/rainbow.png -------------------------------------------------------------------------------- /moon-buggy/resources/weemee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/moon-buggy/resources/weemee.png -------------------------------------------------------------------------------- /moon-buggy/resources/wheel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/moon-buggy/resources/wheel.png -------------------------------------------------------------------------------- /tunnel-1/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-1/.DS_Store -------------------------------------------------------------------------------- /tunnel-1/Main.js: -------------------------------------------------------------------------------- 1 | /* 2 | Tunnel Demo One 3 | Christopher Caleb 4 | http://www.yeahbutisitflash.com 5 | */ 6 | 7 | function Main() 8 | { 9 | // The distance we've travelled through the tunnel. Between 0.0 and 1.0. 10 | this.travelledStep = 0.0; 11 | 12 | // We'll rotate the camera around its z-axis as it moves through the tunnel. 13 | this.rotationStep = 0.0; 14 | 15 | // Create the renderer. 16 | this.webGLRenderer = new THREE.WebGLRenderer(); 17 | this.webGLRenderer.setClearColorHex(0x66FFCC, 1.0); 18 | this.webGLRenderer.setSize(window.innerWidth, window.innerHeight); 19 | $("#WebGL-output").append(this.webGLRenderer.domElement); 20 | 21 | // Create the scene and setup the camera. 22 | this.scene = new THREE.Scene(); 23 | this.camera = new THREE.PerspectiveCamera( 24 | 45, 25 | window.innerWidth / window.innerHeight, 26 | 0.1, 1000 27 | ); 28 | 29 | // Create the tunnel and add it to the scene. 30 | this.geom = this.generateTunnelGeometry(22, 512, 2, 38); 31 | this.tunnel = this.createTunnelMesh(this.geom); 32 | this.scene.add(this.tunnel); 33 | 34 | // Kick off the main loop. 35 | this.render(); 36 | } 37 | 38 | // Constants 39 | Main.TRAVEL_INCREMENT = 0.0004; 40 | Main.ROTATION_INCREMENT = 0.0025; 41 | 42 | Main.prototype.generateTunnelGeometry = function(numPoints, segments, radius, radiusSegments) 43 | { 44 | // Create an array of points that we will generate our spline from. 45 | var points = []; 46 | var prevPoint = new THREE.Vector3(0, 0, 0); 47 | for (var i = 0; i < numPoints; i++) 48 | { 49 | var randomX = prevPoint.x + 10 + Math.round(Math.random() * 50); 50 | var randomY = prevPoint.y + 10 + Math.round(Math.random() * 50); 51 | var randomZ = prevPoint.z + 10 + Math.round(Math.random() * 50); 52 | 53 | prevPoint.x = randomX; 54 | prevPoint.y = randomY; 55 | prevPoint.z = randomZ; 56 | 57 | points.push(new THREE.Vector3(randomX, randomY, randomZ)); 58 | } 59 | 60 | // Generate a spline from our points. 61 | spline = new THREE.SplineCurve3(points); 62 | 63 | // Generate geometry for a tube using our spline. 64 | return new THREE.TubeGeometry(spline, segments, radius, radiusSegments, false); 65 | } 66 | 67 | Main.prototype.createTunnelMesh = function(geom) 68 | { 69 | var material = new THREE.MeshNormalMaterial({transparent: false, opacity: 0.8, side:THREE.DoubleSide}); 70 | return new THREE.Mesh(geom, material); 71 | } 72 | 73 | Main.prototype.render = function() 74 | { 75 | if (this.travelledStep > 1 - Main.TRAVEL_INCREMENT) 76 | { 77 | this.travelledStep = 0.0; 78 | } 79 | 80 | var p1 = spline.getPointAt(this.travelledStep); 81 | var p2 = spline.getPointAt(this.travelledStep + Main.TRAVEL_INCREMENT); 82 | this.camera.position.set(p1.x, p1.y, p1.z); 83 | this.camera.lookAt(p2); 84 | 85 | this.camera.rotation.z = -Math.PI/2 + (Math.sin(this.rotationStep) * Math.PI); 86 | 87 | this.travelledStep += Main.TRAVEL_INCREMENT; 88 | this.rotationStep += Main.ROTATION_INCREMENT; 89 | 90 | requestAnimationFrame(this.render.bind(this)); 91 | this.webGLRenderer.render(this.scene, this.camera); 92 | } 93 | 94 | Main.prototype.resize = function() 95 | { 96 | this.webGLRenderer.setSize(window.innerWidth, window.innerHeight); 97 | this.camera.aspect = window.innerWidth / window.innerHeight; 98 | this.camera.updateProjectionMatrix(); 99 | } 100 | -------------------------------------------------------------------------------- /tunnel-1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Tunnel One 7 | 8 | 9 | 10 | 16 | 17 | 18 |
19 | 28 | 29 | -------------------------------------------------------------------------------- /tunnel-1/particle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-1/particle.png -------------------------------------------------------------------------------- /tunnel-2/Main.js: -------------------------------------------------------------------------------- 1 | /* 2 | Tunnel Demo Two 3 | Christopher Caleb 4 | http://www.yeahbutisitflash.com 5 | */ 6 | 7 | function Main() 8 | { 9 | // The distance we've travelled through the tunnel. Between 0.0 and 1.0. 10 | this.travelledStep = 0.0; 11 | 12 | // We'll rotate the camera around its z-axis as it moves through the tunnel. 13 | this.rotationStep = 0.0; 14 | 15 | // Create the renderer. 16 | this.webGLRenderer = new THREE.WebGLRenderer(); 17 | this.webGLRenderer.setClearColorHex(0x000033, 1.0); 18 | this.webGLRenderer.setSize(window.innerWidth, window.innerHeight); 19 | $("#WebGL-output").append(this.webGLRenderer.domElement); 20 | 21 | // Create the scene and setup the camera. 22 | this.scene = new THREE.Scene(); 23 | this.camera = new THREE.PerspectiveCamera( 24 | 45, 25 | window.innerWidth / window.innerHeight, 26 | 0.1, 1000 27 | ); 28 | 29 | // Create the tunnel and add it to the scene. 30 | this.geom = this.generateTunnelGeometry(22, 256, 2, 28); 31 | this.tunnel = this.createTunnelParticleSystem(this.geom); 32 | this.scene.add(this.tunnel); 33 | 34 | // Kick off the main loop. 35 | this.render(); 36 | } 37 | 38 | // Constants 39 | Main.TRAVEL_INCREMENT = 0.00025; 40 | Main.ROTATION_INCREMENT = 0.0025; 41 | 42 | Main.prototype.generateTunnelGeometry = function(numPoints, segments, radius, radiusSegments) 43 | { 44 | // Create an array of points that we will generate our spline from. 45 | var points = []; 46 | var prevPoint = new THREE.Vector3(0, 0, 0); 47 | for (var i = 0; i < numPoints; i++) 48 | { 49 | var randomX = prevPoint.x + 10 + Math.round(Math.random() * 50); 50 | var randomY = prevPoint.y + 10 + Math.round(Math.random() * 50); 51 | var randomZ = prevPoint.z + 10 + Math.round(Math.random() * 50); 52 | 53 | prevPoint.x = randomX; 54 | prevPoint.y = randomY; 55 | prevPoint.z = randomZ; 56 | 57 | points.push(new THREE.Vector3(randomX, randomY, randomZ)); 58 | } 59 | 60 | // Generate a spline from our points. 61 | spline = new THREE.SplineCurve3(points); 62 | 63 | // Generate geometry for a tube using our spline. 64 | return new THREE.TubeGeometry(spline, segments, radius, radiusSegments, false); 65 | } 66 | 67 | Main.prototype.createTunnelParticleSystem = function(geom) 68 | { 69 | var material = new THREE.ParticleBasicMaterial({ 70 | color: 0xffffff, 71 | size: 3, 72 | transparent: true, 73 | blending: THREE.AdditiveBlending, 74 | map: new THREE.ImageUtils.loadTexture("particle.png") 75 | }); 76 | 77 | var system = new THREE.ParticleSystem(geom, material); 78 | system.sortParticles = true; 79 | 80 | return system; 81 | } 82 | 83 | Main.prototype.render = function() 84 | { 85 | if (this.travelledStep > 1 - Main.TRAVEL_INCREMENT) 86 | { 87 | this.travelledStep = 0.0; 88 | } 89 | 90 | var p1 = spline.getPointAt(this.travelledStep); 91 | var p2 = spline.getPointAt(this.travelledStep + Main.TRAVEL_INCREMENT); 92 | this.camera.position.set(p1.x, p1.y, p1.z); 93 | this.camera.lookAt(p2); 94 | 95 | this.travelledStep += Main.TRAVEL_INCREMENT; 96 | this.rotationStep += Main.ROTATION_INCREMENT; 97 | 98 | requestAnimationFrame(this.render.bind(this)); 99 | this.webGLRenderer.render(this.scene, this.camera); 100 | } 101 | 102 | Main.prototype.resize = function() 103 | { 104 | this.webGLRenderer.setSize(window.innerWidth, window.innerHeight); 105 | this.camera.aspect = window.innerWidth / window.innerHeight; 106 | this.camera.updateProjectionMatrix(); 107 | } 108 | -------------------------------------------------------------------------------- /tunnel-2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Tunnel Two 7 | 8 | 9 | 10 | 16 | 17 | 18 |
19 | 28 | 29 | -------------------------------------------------------------------------------- /tunnel-2/particle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-2/particle.png -------------------------------------------------------------------------------- /tunnel-3/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/.DS_Store -------------------------------------------------------------------------------- /tunnel-3/Bullet.js: -------------------------------------------------------------------------------- 1 | /* 2 | Intergalactic Highway Demo 3 | 4 | Bullet/Projectile 5 | Christopher Caleb 6 | http://www.yeahbutisitflash.com 7 | */ 8 | 9 | function Bullet(spline, onExpired) 10 | { 11 | THREE.Object3D.call(this); 12 | 13 | this.spline = spline; 14 | this.onExpired = onExpired; 15 | this.travelledRatio = 0; 16 | this.rotationWhenFired = 0; 17 | this.velocity = 0; 18 | this.lifespan = 0; 19 | 20 | this.add(this.createBulletMesh()); 21 | } 22 | 23 | Bullet.constructor = Bullet; 24 | Bullet.prototype = Object.create(THREE.Object3D.prototype); 25 | 26 | Bullet.INIT_LIFESPAN = 240; 27 | Bullet.VELOCITY = 0.001; 28 | Bullet.LOOK_AHEAD = 0.0001; 29 | 30 | Bullet.prototype.createBulletMesh = function() 31 | { 32 | var geometry = new THREE.SphereGeometry(0.25); 33 | var material = new THREE.MeshPhongMaterial({color:0xffffff}); 34 | var mesh = new THREE.Mesh(geometry, material); 35 | mesh.position.set(0, 6, 0); 36 | 37 | return mesh; 38 | } 39 | 40 | Bullet.prototype.fire = function(velocity, travelledRatio, rotation) { 41 | this.velocity = Bullet.VELOCITY + velocity; 42 | this.travelledRatio = travelledRatio; 43 | this.rotationWhenFired = rotation; 44 | this.lifespan = Bullet.INIT_LIFESPAN; 45 | 46 | var p1 = this.spline.getPointAt(travelledRatio); 47 | var p2 = this.spline.getPointAt(travelledRatio + Bullet.LOOK_AHEAD); 48 | this.position.set(p1.x, p1.y, p1.z); 49 | this.lookAt(p2); 50 | this.rotation.z = rotation; 51 | } 52 | 53 | Bullet.prototype.update = function() { 54 | this.travelledRatio += this.velocity; 55 | this.lifespan--; 56 | 57 | if (this.travelledRatio + Bullet.LOOK_AHEAD >= 1 || this.lifespan == 0) 58 | { 59 | if (this.onExpired != null) 60 | { 61 | this.onExpired(this); 62 | } 63 | } 64 | else 65 | { 66 | var p1 = this.spline.getPointAt(this.travelledRatio); 67 | var p2 = this.spline.getPointAt(this.travelledRatio + Bullet.LOOK_AHEAD); 68 | this.position.set(p1.x, p1.y, p1.z); 69 | this.lookAt(p2); 70 | this.rotation.z = this.rotationWhenFired; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tunnel-3/Earth.js: -------------------------------------------------------------------------------- 1 | /* 2 | Intergalactic Highway Demo 3 | 4 | Planet Earth 5 | Christopher Caleb 6 | http://www.yeahbutisitflash.com 7 | */ 8 | 9 | function Earth() 10 | { 11 | THREE.Object3D.call(this); 12 | 13 | this.mesh = this.createMesh(new THREE.SphereGeometry(200, 80, 80)); 14 | this.rotation.x += Math.PI / 2; 15 | 16 | this.add(this.mesh); 17 | } 18 | 19 | Earth.constructor = Earth; 20 | Earth.prototype = Object.create(THREE.Object3D.prototype); 21 | 22 | Earth.prototype.createMesh = function(geometry) { 23 | var planetTexture = THREE.ImageUtils.loadTexture("resources/earth/Earth.png"); 24 | var specularTexture = THREE.ImageUtils.loadTexture("resources/earth/EarthSpec.png"); 25 | var normalTexture = THREE.ImageUtils.loadTexture("resources/earth/EarthNormal.png"); 26 | 27 | var material = new THREE.MeshPhongMaterial(); 28 | material.specularMap = specularTexture; 29 | material.specular = new THREE.Color(0x4444aa); 30 | material.normalMap = normalTexture; 31 | material.map = planetTexture; 32 | 33 | var mesh = THREE.SceneUtils.createMultiMaterialObject(geometry, [material]); 34 | return mesh; 35 | }; 36 | 37 | Earth.prototype.update = function() { 38 | this.rotation.y += 0.001; 39 | }; 40 | -------------------------------------------------------------------------------- /tunnel-3/Highway.js: -------------------------------------------------------------------------------- 1 | /* 2 | Intergalactic Highway Demo 3 | 4 | Highway Spline 5 | Christopher Caleb 6 | http://www.yeahbutisitflash.com 7 | */ 8 | 9 | function Highway() 10 | { 11 | THREE.Object3D.call(this); 12 | 13 | this.spline = null; 14 | this.earthPosition = new THREE.Vector3(); 15 | 16 | var geometry = this.generateGeometry(22, 256, 4, 24); 17 | var particileSystem = this.createParticleSystem(geometry); 18 | 19 | this.add(particileSystem); 20 | } 21 | 22 | Highway.constructor = Highway; 23 | Highway.prototype = Object.create(THREE.Object3D.prototype); 24 | 25 | Highway.prototype.getSpline = function() 26 | { 27 | return this.spline; 28 | }; 29 | 30 | Highway.prototype.getEarthPosition = function() 31 | { 32 | return this.earthPosition; 33 | }; 34 | 35 | Highway.prototype.generateGeometry = function(numPoints, segments, radius, radiusSegments) 36 | { 37 | // Create an array of points that we will generate our spline from. 38 | var points = []; 39 | var prevPoint = new THREE.Vector3(0, 0, 0); 40 | for (var i = 0; i < numPoints; i++) 41 | { 42 | var randomX = prevPoint.x + 10 + Math.round(Math.random() * 50); 43 | var randomY = prevPoint.y + 10 + Math.round(Math.random() * 50); 44 | var randomZ = prevPoint.z - 10 - Math.round(Math.random() * 50); 45 | 46 | prevPoint.x = randomX; 47 | prevPoint.y = randomY; 48 | prevPoint.z = randomZ; 49 | 50 | points.push(new THREE.Vector3(randomX, randomY, randomZ)); 51 | } 52 | 53 | var dist = 4; 54 | var index = (numPoints - dist) + Math.floor(Math.random() * dist); 55 | this.earthPosition.set(points[index].x, points[index].y - 300, points[index].z) 56 | 57 | // Generate a spline from our points. 58 | this.spline = new THREE.SplineCurve3(points); 59 | 60 | // Generate geometry for a tube using our spline. 61 | return new THREE.TubeGeometry(this.spline, segments, radius, radiusSegments, false); 62 | }; 63 | 64 | Highway.prototype.createParticleSystem = function(geometry) 65 | { 66 | var material = new THREE.ParticleBasicMaterial({ 67 | color: 0xffffff, 68 | size: 3, 69 | transparent: true, 70 | blending: THREE.AdditiveBlending, 71 | map: new THREE.ImageUtils.loadTexture("resources/particle.png") 72 | }); 73 | 74 | var system = new THREE.ParticleSystem(geometry, material); 75 | system.sortParticles = true; 76 | 77 | return system; 78 | }; 79 | 80 | -------------------------------------------------------------------------------- /tunnel-3/Main.js: -------------------------------------------------------------------------------- 1 | /* 2 | Intergalactic Highway Demo 3 | 4 | Main Application Class 5 | Christopher Caleb 6 | http://www.yeahbutisitflash.com 7 | */ 8 | 9 | function Main() 10 | { 11 | this.webGLRenderer = new THREE.WebGLRenderer(); 12 | this.webGLRenderer.setClearColorHex(0x11171c, 1.0); 13 | this.webGLRenderer.setSize(window.innerWidth, window.innerHeight); 14 | this.webGLRenderer.shadowMapEnabled = true; 15 | $("#WebGL-output").append(this.webGLRenderer.domElement); 16 | 17 | this.scene = new THREE.Scene(); 18 | this.camera = new THREE.PerspectiveCamera( 19 | 45, 20 | window.innerWidth / window.innerHeight, 21 | 0.1, 1400 22 | ); 23 | 24 | var ambi = new THREE.AmbientLight(0x181818); 25 | this.scene.add(ambi); 26 | 27 | this.contentToLoad = 2; 28 | 29 | this.createHighway(); 30 | this.createEarth(); 31 | this.createObstacles(); 32 | this.createSkybox(); 33 | this.createBullets(); 34 | 35 | var loader = new THREE.OBJMTLLoader(); 36 | loader.addEventListener('load', this.spaceshipLoaded.bind(this)); 37 | loader.load('resources/spaceship/spaceship.obj', 'resources/spaceship/spaceship.mtl'); 38 | } 39 | 40 | Main.prototype.createHighway = function() 41 | { 42 | this.highway = new Highway(); 43 | this.scene.add(this.highway); 44 | }; 45 | 46 | Main.prototype.createEarth = function() 47 | { 48 | this.earth = new Earth(); 49 | this.earth.position = this.highway.getEarthPosition(); 50 | this.scene.add(this.earth); 51 | }; 52 | 53 | Main.prototype.createSkybox = function() 54 | { 55 | this.skybox = new Skybox(this.skyboxLoaded.bind(this)); 56 | this.scene.add(this.skybox); 57 | }; 58 | 59 | Main.prototype.spaceshipLoaded = function(event) 60 | { 61 | this.contentToLoad--; 62 | 63 | this.spaceship = new Spaceship(event.content, this.highway.getSpline(), this.camera); 64 | this.scene.add(this.spaceship); 65 | 66 | this.checkResourcesLoaded(); 67 | }; 68 | 69 | Main.prototype.skyboxLoaded = function(event) 70 | { 71 | this.contentToLoad--; 72 | this.checkResourcesLoaded(); 73 | }; 74 | 75 | Main.prototype.checkResourcesLoaded = function() 76 | { 77 | if (this.contentToLoad == 0) 78 | { 79 | removeSpinner(); 80 | this.render(); 81 | } 82 | }; 83 | 84 | Main.prototype.createObstacles = function() 85 | { 86 | this.obstacles = []; 87 | for (var i = 1; i < 5; i++) 88 | { 89 | var obstacle = new Obstacle(this.highway.getSpline(), i * 0.2); 90 | this.obstacles.push(obstacle); 91 | this.scene.add(obstacle); 92 | } 93 | } 94 | 95 | Main.prototype.createBullets = function() 96 | { 97 | this.bullets = []; 98 | this.bulletsInUse = []; 99 | for (var i = 0; i < 20; i++) 100 | { 101 | this.bullets.push(new Bullet(this.highway.getSpline(), this.bulletExpired.bind(this))); 102 | } 103 | } 104 | 105 | Main.prototype.bulletExpired = function(b) { 106 | var foundAt = -1; 107 | for (var i = 0; i < this.bulletsInUse.length; i++) 108 | { 109 | if (this.bulletsInUse[i] == b) 110 | { 111 | foundAt = i; 112 | break; 113 | } 114 | } 115 | 116 | if (foundAt != -1) 117 | { 118 | this.bulletsInUse.splice(foundAt, 1); 119 | this.bullets.push(b); 120 | this.scene.remove(b); 121 | } 122 | } 123 | 124 | Main.prototype.render = function() 125 | { 126 | for (var i = 0; i < this.bulletsInUse.length; i++) 127 | { 128 | this.bulletsInUse[i].update(); 129 | } 130 | 131 | for (var i = 0; i < this.obstacles.length; i++) 132 | { 133 | this.obstacles[i].update(); 134 | } 135 | 136 | this.earth.update(); 137 | this.spaceship.update(); 138 | this.skybox.position = this.spaceship.position; 139 | 140 | requestAnimationFrame(this.render.bind(this)); 141 | this.webGLRenderer.render(this.scene, this.camera); 142 | } 143 | 144 | Main.prototype.resize = function() 145 | { 146 | this.webGLRenderer.setSize(window.innerWidth, window.innerHeight); 147 | this.camera.aspect = window.innerWidth / window.innerHeight; 148 | this.camera.updateProjectionMatrix(); 149 | } 150 | 151 | Main.prototype.startRotation = function(angle) 152 | { 153 | this.spaceship.startRotation(angle); 154 | } 155 | 156 | Main.prototype.stopRotation = function() 157 | { 158 | this.spaceship.stopRotation(); 159 | } 160 | 161 | Main.prototype.fire = function() 162 | { 163 | if (this.bullets.length > 0) 164 | { 165 | var bullet = this.bullets.shift(); 166 | this.bulletsInUse.push(bullet); 167 | bullet.fire( 168 | this.spaceship.getVelocity(), 169 | this.spaceship.getTravelledRatio(), 170 | this.spaceship.getRotation() 171 | ); 172 | this.scene.add(bullet); 173 | } 174 | } 175 | 176 | Main.prototype.boost = function() 177 | { 178 | this.spaceship.boost(); 179 | } 180 | -------------------------------------------------------------------------------- /tunnel-3/Obstacle.js: -------------------------------------------------------------------------------- 1 | /* 2 | Intergalactic Highway Demo 3 | 4 | Obstacle 5 | Christopher Caleb 6 | http://www.yeahbutisitflash.com 7 | */ 8 | 9 | function Obstacle(spline, travelledRatio) 10 | { 11 | THREE.Object3D.call(this); 12 | 13 | this.spline = spline; 14 | this.travelledRatio = travelledRatio; 15 | 16 | var p1 = this.spline.getPointAt(travelledRatio); 17 | var p2 = this.spline.getPointAt(travelledRatio + Obstacle.LOOK_AHEAD); 18 | this.position.set(p1.x, p1.y, p1.z); 19 | this.lookAt(p2); 20 | this.rotation.z = (Math.PI * 2) * Math.random(); 21 | this.rotationInc = Math.random() / 75; 22 | if (Math.random() < 0.5) { 23 | this.rotationInc = -this.rotationInc; 24 | } 25 | 26 | this.add(this.createObstacleMesh()); 27 | } 28 | 29 | Obstacle.constructor = Obstacle; 30 | Obstacle.prototype = Object.create(THREE.Object3D.prototype); 31 | 32 | Obstacle.LOOK_AHEAD = 0.0001; 33 | 34 | Obstacle.prototype.createObstacleMesh = function() 35 | { 36 | var geometry = new THREE.TorusGeometry(6, 1, 6, 13, (4.5 + Math.random())); 37 | var material = new THREE.MeshPhongMaterial({color: 0x0066cc, side:THREE.DoubleSide}); 38 | var mesh = new THREE.Mesh(geometry, material); 39 | mesh.position.set(0, 0, 0); 40 | 41 | return mesh; 42 | } 43 | 44 | Obstacle.prototype.update = function() 45 | { 46 | this.rotation.z += this.rotationInc; 47 | } 48 | -------------------------------------------------------------------------------- /tunnel-3/Skybox.js: -------------------------------------------------------------------------------- 1 | /* 2 | Intergalactic Highway Demo 3 | 4 | Skybox 5 | Christopher Caleb 6 | http://www.yeahbutisitflash.com 7 | */ 8 | 9 | function Skybox(onLoaded) 10 | { 11 | THREE.Object3D.call(this); 12 | 13 | this.onLoaded = onLoaded; 14 | 15 | var texture = this.createTexture(); 16 | var shader = this.createShader(texture); 17 | var material = this.createMaterial(shader); 18 | var mesh = new THREE.Mesh(new THREE.CubeGeometry(1000, 1000, 1000), material); 19 | 20 | this.add(mesh); 21 | } 22 | 23 | Skybox.constructor = Skybox; 24 | Skybox.prototype = Object.create(THREE.Object3D.prototype); 25 | 26 | Skybox.prototype.createTexture = function() 27 | { 28 | var path = "resources/cubemap/"; 29 | var format = '.jpg'; 30 | var urls = [ 31 | path + 'posx' + format, path + 'negx' + format, 32 | path + 'posy' + format, path + 'negy' + format, 33 | path + 'posz' + format, path + 'negz' + format 34 | ]; 35 | 36 | var texture = THREE.ImageUtils.loadTextureCube(urls, null, this.texturesLoaded.bind(this)); 37 | 38 | return texture; 39 | }; 40 | 41 | Skybox.prototype.createShader = function(texture) 42 | { 43 | var shader = THREE.ShaderLib[ "cube" ]; 44 | shader.uniforms[ "tCube" ].value = texture; 45 | 46 | return shader; 47 | }; 48 | 49 | Skybox.prototype.createMaterial = function(shader) 50 | { 51 | var material = new THREE.ShaderMaterial({ 52 | fragmentShader: shader.fragmentShader, 53 | vertexShader: shader.vertexShader, 54 | uniforms: shader.uniforms, 55 | depthWrite: false, 56 | side: THREE.BackSide 57 | }); 58 | 59 | return material; 60 | }; 61 | 62 | Skybox.prototype.texturesLoaded = function(e) 63 | { 64 | if (this.onLoaded != null) 65 | { 66 | this.onLoaded(e); 67 | } 68 | }; 69 | -------------------------------------------------------------------------------- /tunnel-3/Spaceship.js: -------------------------------------------------------------------------------- 1 | /* 2 | Intergalactic Highway Demo 3 | 4 | Spaceship 5 | Christopher Caleb 6 | http://www.yeahbutisitflash.com 7 | */ 8 | 9 | function Spaceship(spaceshipObject, spline, camera) 10 | { 11 | THREE.Object3D.call(this); 12 | 13 | this.spline = spline; 14 | this.camera = camera; 15 | this.spaceship = spaceshipObject; 16 | 17 | this.travelledRatio = 0; 18 | this.shipRotationStep = 0; 19 | this.shipRotation = 0; 20 | this.playerVel = Spaceship.PLAYER_STANDARD_VEL; 21 | this.boostLifespan = 10; 22 | this.boostAcc = 0.000025; 23 | this.boostDec = 0.000012; 24 | this.boostActivated = false; 25 | 26 | this.setupSpaceship(spaceshipObject); 27 | 28 | var pointLight1 = new THREE.PointLight(0xffffff); 29 | pointLight1.position.set(0, 40, -80); 30 | pointLight1.intensity = 1.0; 31 | this.add(pointLight1); 32 | 33 | var pointLight2 = new THREE.PointLight(0xffffff); 34 | pointLight2.position.set(0, 7, 0); 35 | pointLight2.intensity = 8; 36 | pointLight2.distance = 3.15; 37 | this.add(pointLight2); 38 | 39 | this.add(camera); 40 | 41 | camera.rotation.y = Math.PI; 42 | camera.position.set(0,9,-15); 43 | } 44 | 45 | Spaceship.constructor = Spaceship; 46 | Spaceship.prototype = Object.create(THREE.Object3D.prototype); 47 | 48 | Spaceship.LOOK_AHEAD = 0.0001; 49 | Spaceship.PLAYER_STANDARD_VEL = 0.00035; 50 | Spaceship.PLAYER_MAX_VELOCITY = 0.0018; 51 | 52 | Spaceship.prototype.setupSpaceship = function(object3D) 53 | { 54 | object3D.children[0].visible = false; 55 | object3D.children[1].children[0].visible = false; 56 | object3D.children[2].children[0].visible = false; 57 | object3D.children[3].children[0].visible = false; 58 | object3D.scale.set(0.5, 0.5, 0.5); 59 | object3D.position.set(0.15, 5, 0); 60 | 61 | this.add(object3D); 62 | } 63 | 64 | Spaceship.prototype.getVelocity = function() 65 | { 66 | return this.playerVel; 67 | } 68 | 69 | Spaceship.prototype.getTravelledRatio = function() 70 | { 71 | return this.travelledRatio; 72 | } 73 | 74 | Spaceship.prototype.getRotation = function() 75 | { 76 | return this.shipRotation; 77 | } 78 | 79 | Spaceship.prototype.update = function() 80 | { 81 | // Loop back round if we get to the end of the spline. 82 | if (this.travelledRatio > 1 - Spaceship.LOOK_AHEAD) 83 | { 84 | this.travelledRatio = 0; 85 | } 86 | 87 | // Position the player and the camera. 88 | var p1 = this.spline.getPointAt(this.travelledRatio); 89 | var p2 = this.spline.getPointAt(this.travelledRatio + Spaceship.LOOK_AHEAD); 90 | this.position.set(p1.x, p1.y, p1.z); 91 | this.shipRotation += this.shipRotationStep; 92 | this.lookAt(p2); 93 | this.rotation.z = this.shipRotation; 94 | 95 | // Update the player's position on the spline and their rotation. 96 | if (this.boostActivated && this.boostLifespan > 0) 97 | { 98 | this.boostLifespan--; 99 | this.playerVel += this.boostAcc; 100 | if (this.playerVel > Spaceship.PLAYER_MAX_VELOCITY) 101 | { 102 | this.playerVel = Spaceship.PLAYER_MAX_VELOCITY; 103 | } 104 | this.travelledRatio += this.playerVel; 105 | } 106 | else if (this.boostActivated && this.boostLifespan <= 0) 107 | { 108 | this.boostLifespan--; 109 | this.playerVel -= this.boostDec; 110 | if (this.playerVel <= Spaceship.PLAYER_STANDARD_VEL) 111 | { 112 | this.playerVel = Spaceship.PLAYER_STANDARD_VEL; 113 | this.travelledStep += this.playerVel; 114 | this.boostActivated = false; 115 | } 116 | this.travelledRatio += this.playerVel; 117 | } 118 | else if (!this.boostActivated) 119 | { 120 | this.travelledRatio += this.playerVel; 121 | } 122 | } 123 | 124 | Spaceship.prototype.startRotation = function(angle) 125 | { 126 | this.shipRotationStep = angle; 127 | if (angle > 0) 128 | { 129 | this.spaceship.rotation.z = Math.PI / 45; 130 | } 131 | else if (angle < 0) 132 | { 133 | this.spaceship.rotation.z = -Math.PI / 45; 134 | } 135 | } 136 | 137 | Spaceship.prototype.stopRotation = function() 138 | { 139 | this.shipRotationStep = 0; 140 | this.spaceship.rotation.z = 0; 141 | } 142 | 143 | Spaceship.prototype.boost = function() 144 | { 145 | this.boostLifespan = 45; 146 | this.boostActivated = true; 147 | } 148 | -------------------------------------------------------------------------------- /tunnel-3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Intergalactive Highway 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |
25 |
26 |
27 |
28 |
29 | 72 | 73 | -------------------------------------------------------------------------------- /tunnel-3/misc.js: -------------------------------------------------------------------------------- 1 | /* 2 | Intergalactic Highway Demo 3 | 4 | Some Support Functions 5 | Christopher Caleb 6 | http://www.yeahbutisitflash.com 7 | */ 8 | 9 | var spinnerRotation = 0; 10 | var spinnerId = null; 11 | var keyOverlayOpacity = 1; 12 | 13 | function setupLoadingSpinner() { 14 | spinnerId = setInterval(updateSpinner, 1000/60); 15 | //rotateSpinner(90); 16 | resizeUI(); 17 | } 18 | 19 | function updateSpinner() { 20 | spinnerRotation += 4; 21 | rotateSpinner(spinnerRotation); 22 | } 23 | 24 | function rotateSpinner(d) { 25 | $("#spinner").css({'top': (window.innerHeight - 261) / 2}); 26 | $("#spinner").css({'left': (window.innerWidth - 261) / 2}); 27 | $("#spinner").css({ 28 | '-moz-transform': 'rotate(' + d + 'deg)', 29 | '-webkit-transform': 'rotate(' + d + 'deg)', 30 | '-o-transform': 'rotate(' + d + 'deg)', 31 | '-ms-transform': 'rotate(' + d + 'deg)', 32 | 'transform': 'rotate(' + d + 'deg)' 33 | }); 34 | } 35 | 36 | function removeSpinner() { 37 | $("#spinner").css({'visibility': 'hidden'}); 38 | $("#rotateLeft").css({'visibility': 'visible'}); 39 | $("#rotateRight").css({'visibility': 'visible'}); 40 | $("#shoot").css({'visibility': 'visible'}); 41 | $("#boost").css({'visibility': 'visible'}); 42 | clearInterval(spinnerId); 43 | } 44 | 45 | function reduceKeyOverlayOpacity() { 46 | keyOverlayOpacity -= 0.05; 47 | if (keyOverlayOpacity < 0) keyOverlayOpacity = 0; 48 | $("#rotateLeft").css({'opacity':keyOverlayOpacity}); 49 | $("#rotateRight").css({'opacity':keyOverlayOpacity}); 50 | $("#shoot").css({'opacity':keyOverlayOpacity}); 51 | $("#boost").css({'opacity':keyOverlayOpacity}); 52 | } 53 | 54 | function resizeUI() { 55 | var w = $("#shoot").css('width'); 56 | w = parseInt(w); 57 | var posX = (window.innerWidth - w) / 2; 58 | $("#shoot").css({'left':posX + 'px'}); 59 | 60 | w = $("#boost").css('width'); 61 | w = parseInt(w); 62 | posX = (window.innerWidth - w) / 2; 63 | $("#boost").css({'left':posX + 'px'}); 64 | } 65 | -------------------------------------------------------------------------------- /tunnel-3/resources/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/.DS_Store -------------------------------------------------------------------------------- /tunnel-3/resources/cubemap/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/cubemap/.DS_Store -------------------------------------------------------------------------------- /tunnel-3/resources/cubemap/negx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/cubemap/negx.jpg -------------------------------------------------------------------------------- /tunnel-3/resources/cubemap/negy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/cubemap/negy.jpg -------------------------------------------------------------------------------- /tunnel-3/resources/cubemap/negz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/cubemap/negz.jpg -------------------------------------------------------------------------------- /tunnel-3/resources/cubemap/posx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/cubemap/posx.jpg -------------------------------------------------------------------------------- /tunnel-3/resources/cubemap/posy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/cubemap/posy.jpg -------------------------------------------------------------------------------- /tunnel-3/resources/cubemap/posz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/cubemap/posz.jpg -------------------------------------------------------------------------------- /tunnel-3/resources/earth/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/earth/.DS_Store -------------------------------------------------------------------------------- /tunnel-3/resources/earth/Earth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/earth/Earth.png -------------------------------------------------------------------------------- /tunnel-3/resources/earth/EarthNormal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/earth/EarthNormal.png -------------------------------------------------------------------------------- /tunnel-3/resources/earth/EarthSpec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/earth/EarthSpec.png -------------------------------------------------------------------------------- /tunnel-3/resources/particle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/particle.png -------------------------------------------------------------------------------- /tunnel-3/resources/spaceship/spaceship.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'spaceship001.blend' 2 | # Material Count: 6 3 | 4 | newmtl Material.001 5 | Ns 96.078431 6 | Ka 0.000000 0.000000 0.000000 7 | Kd 0.058160 0.058160 0.058160 8 | Ks 0.000000 0.000000 0.000000 9 | Ni 1.000000 10 | d 1.000000 11 | illum 1 12 | 13 | newmtl Material.002 14 | Ns 96.078431 15 | Ka 0.000000 0.000000 0.000000 16 | Kd 0.020067 0.023271 0.031742 17 | Ks 0.000000 0.000000 0.000000 18 | Ni 1.000000 19 | d 1.000000 20 | illum 1 21 | 22 | newmtl Material.003 23 | Ns 11.764706 24 | Ka 0.000000 0.000000 0.000000 25 | Kd 0.207833 0.078579 0.035756 26 | Ks 0.070175 0.070175 0.070175 27 | Ni 1.000000 28 | d 1.000000 29 | illum 2 30 | 31 | newmtl Material.006 32 | Ns 96.078431 33 | Ka 0.000000 0.000000 0.000000 34 | Kd 0.248644 0.010823 0.000000 35 | Ks 0.000000 0.000000 0.000000 36 | Ni 1.000000 37 | d 1.000000 38 | illum 1 39 | 40 | newmtl Material.007 41 | Ns 96.078431 42 | Ka 0.000000 0.000000 0.000000 43 | Kd 0.241641 0.241641 0.241641 44 | Ks 0.500000 0.500000 0.500000 45 | Ni 1.000000 46 | d 1.000000 47 | illum 2 48 | 49 | newmtl Material.008 50 | Ns 96.078431 51 | Ka 0.000000 0.000000 0.000000 52 | Kd 0.640000 0.640000 0.640000 53 | Ks 0.500000 0.500000 0.500000 54 | Ni 1.000000 55 | d 1.000000 56 | illum 2 57 | -------------------------------------------------------------------------------- /tunnel-3/resources/ui/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/ui/.DS_Store -------------------------------------------------------------------------------- /tunnel-3/resources/ui/boost-key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/ui/boost-key.png -------------------------------------------------------------------------------- /tunnel-3/resources/ui/rotate-left-key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/ui/rotate-left-key.png -------------------------------------------------------------------------------- /tunnel-3/resources/ui/rotate-right-key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/ui/rotate-right-key.png -------------------------------------------------------------------------------- /tunnel-3/resources/ui/shoot-key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/ui/shoot-key.png -------------------------------------------------------------------------------- /tunnel-3/resources/ui/spinner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccaleb/threejs-experiments/acad94b2905341dd7e623dc6b44fa8810f08e670/tunnel-3/resources/ui/spinner.png -------------------------------------------------------------------------------- /tunnel-3/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #11171c; 3 | margin: 0; 4 | overflow: hidden; 5 | } 6 | 7 | #spinner { 8 | position: fixed; 9 | top: 200px; 10 | left: 200px; 11 | } 12 | 13 | #rotateLeft { 14 | position: fixed; 15 | top: 45%; 16 | left: 5%; 17 | visibility: hidden; 18 | } 19 | 20 | #rotateRight { 21 | position: fixed; 22 | top: 45%; 23 | right: 5%; 24 | visibility: hidden; 25 | } 26 | 27 | #shoot { 28 | position: fixed; 29 | top: 20%; 30 | visibility: hidden; 31 | } 32 | 33 | #boost { 34 | position: fixed; 35 | top: 5%; 36 | visibility: hidden; 37 | } --------------------------------------------------------------------------------