├── .gitignore ├── .npmignore ├── LICENSE ├── Makefile ├── README.md ├── example ├── hellokinect │ ├── depthbuffer_sample.js │ └── hellokinect.js └── simpleviewer │ ├── package.json │ ├── public │ ├── javascripts │ │ ├── Detector.js │ │ ├── ShaderExtras.js │ │ ├── Stats.js │ │ ├── Three.js │ │ ├── kinect.js │ │ ├── main.js │ │ ├── postprocessing │ │ │ ├── BloomPass.js │ │ │ ├── DotScreenPass.js │ │ │ ├── EffectComposer.js │ │ │ ├── FilmPass.js │ │ │ ├── MaskPass.js │ │ │ ├── RenderPass.js │ │ │ ├── SavePass.js │ │ │ ├── ShaderPass.js │ │ │ └── TexturePass.js │ │ ├── socket.io.js │ │ └── webgl.js │ └── stylesheets │ │ └── style.css │ ├── server.js │ └── views │ ├── 404.ejs │ ├── 500.ejs │ ├── index.ejs │ ├── layout.ejs │ └── webgl.ejs ├── freenect.js ├── package.json ├── src └── node_freenect.cc └── wscript /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | node_modules 3 | .lock-wscript 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .git* 2 | .DS_Store 3 | .lock-wscript 4 | example/ 5 | node_modules/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | make: 2 | node-waf configure clean build; 3 | 4 | clean: 5 | rm -rf ./build 6 | 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | node-freenect 2 | ============= 3 | 4 | This software is Node.js addon for control Microsoft Kinect device, 5 | bindings for [libfreenect](https://github.com/OpenKinect/libfreenect). 6 | 7 | 8 | This addon can work on Mac OS X environment, maybe linux environment could work. 9 | 10 | It cannot work on Windows environment. 11 | 12 | Requirements 13 | ------------ 14 | 15 | For the addon, you'll need 16 | 17 | * Mac OS X >= 10.6 18 | * Node.js >= 0.4.0 19 | * libfreenect 20 | * libusb-freenect on Mac OS X, libusb-1.0-dev on Linux 21 | * python >= 2.6 22 | 23 | Installation 24 | ------------ 25 | 26 | Just clone this repository, and using npm. 27 | 28 | npm install 29 | 30 | 31 | Licence 32 | ------- 33 | 34 | Copyright 2011 Kazuyuki Honda 35 | 36 | Licensed under the Apache License, Version 2.0 (the "License"); 37 | you may not use this file except in compliance with the License. 38 | You may obtain a copy of the License at 39 | 40 | http://www.apache.org/licenses/LICENSE-2.0 41 | 42 | Unless required by applicable law or agreed to in writing, software 43 | distributed under the License is distributed on an "AS IS" BASIS, 44 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 45 | See the License for the specific language governing permissions and 46 | limitations under the License. 47 | -------------------------------------------------------------------------------- /example/hellokinect/depthbuffer_sample.js: -------------------------------------------------------------------------------- 1 | var Freenect = require('freenect'); 2 | 3 | var kinect = new Freenect.Kinect(), 4 | ledOption = 0, 5 | prev = Date.now(); 6 | 7 | setInterval(function() { 8 | var now = Date.now(), 9 | interval = now - prev, 10 | depth = kinect.getDepthBuffer(), 11 | len = depth.length, 12 | tiltAngle = kinect.getTiltAngle(), 13 | i; 14 | 15 | console.log('Interval: %d, Depth Size: %d, LED Option: %d, Tile Angle: %d', 16 | interval, len, ledOption, tiltAngle); 17 | 18 | // Manupulate depth pixel data like following code. 19 | for (i = 0; i < len; ++i) { 20 | depth[i] = 255 - depth[i]; 21 | } 22 | 23 | // Change LED color and blink pattern. 24 | kinect.setLed(ledOption); 25 | 26 | ledOption += 1; 27 | if (ledOption > 6) { 28 | ledOption = 0 29 | } 30 | 31 | prev = now; 32 | 33 | }, 100); 34 | -------------------------------------------------------------------------------- /example/hellokinect/hellokinect.js: -------------------------------------------------------------------------------- 1 | var Freenect = require('freenect'); 2 | 3 | var kinect = new Freenect.Kinect(), 4 | ledOption = 0, 5 | prev = Date.now(); 6 | 7 | setInterval(function() { 8 | var now = Date.now(), 9 | interval = now - prev, 10 | depth = kinect.getDepth(), 11 | len = depth.length, 12 | tiltAngle = kinect.getTiltAngle(), 13 | i; 14 | 15 | console.log('Interval: %d, Depth Size: %d, LED Option: %d, Tile Angle: %d', 16 | interval, len, ledOption, tiltAngle); 17 | 18 | // Manupulate depth pixel data like following code. 19 | for (i = 0; i < len; ++i) { 20 | depth[i] = 255 - depth[i]; 21 | } 22 | 23 | // Change LED color and blink pattern. 24 | kinect.setLed(ledOption); 25 | 26 | ledOption += 1; 27 | if (ledOption > 6) { 28 | ledOption = 0 29 | } 30 | 31 | prev = now; 32 | 33 | }, 200); 34 | -------------------------------------------------------------------------------- /example/simpleviewer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simpleviewer", 3 | "description": "A simple node-freenect viewer for kinect with Node.", 4 | "version": "0.0.1", 5 | "homepage": "https://github.com/hakobera/node-freenect", 6 | "author": "Kazuyuki Honda ", 7 | "directories": { 8 | "public": "./public" 9 | }, 10 | "engine": { 11 | "node": ">=-0.4.0" 12 | }, 13 | "dependencies": { 14 | "express": "2.2.2", 15 | "connect": "1.3.0", 16 | "ejs": "0.4.1", 17 | "socket.io": "0.6.17", 18 | "browserify": "0.3.1", 19 | "jsmin": "1.0.0" 20 | }, 21 | "bin": { 22 | "simpleviewer": "./server.js" 23 | } 24 | } -------------------------------------------------------------------------------- /example/simpleviewer/public/javascripts/Detector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * @author mr.doob / http://mrdoob.com/ 4 | */ 5 | 6 | Detector = { 7 | 8 | canvas: !! window.CanvasRenderingContext2D, 9 | webgl: ( function () { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } } )(), 10 | workers: !! window.Worker, 11 | fileapi: window.File && window.FileReader && window.FileList && window.Blob, 12 | 13 | getWebGLErrorMessage: function () { 14 | 15 | var element = document.createElement( 'div' ); 16 | element.id = 'webgl-error-message'; 17 | element.style.fontFamily = 'monospace'; 18 | element.style.fontSize = '13px'; 19 | element.style.fontWeight = 'normal'; 20 | element.style.textAlign = 'center'; 21 | element.style.background = '#fff'; 22 | element.style.color = '#000'; 23 | element.style.padding = '1.5em'; 24 | element.style.width = '400px'; 25 | element.style.margin = '5em auto 0'; 26 | 27 | if ( ! this.webgl ) { 28 | 29 | element.innerHTML = window.WebGLRenderingContext ? [ 30 | 'Your graphics card does not seem to support WebGL.
', 31 | 'Find out how to get it here.' 32 | ].join( '\n' ) : [ 33 | 'Your browser does not seem to support WebGL.
', 34 | 'Find out how to get it here.' 35 | ].join( '\n' ); 36 | 37 | } 38 | 39 | return element; 40 | 41 | }, 42 | 43 | addGetWebGLMessage: function ( parameters ) { 44 | 45 | var parent, id, element; 46 | 47 | parameters = parameters || {}; 48 | 49 | parent = parameters.parent !== undefined ? parameters.parent : document.body; 50 | id = parameters.id !== undefined ? parameters.id : 'oldie'; 51 | 52 | element = Detector.getWebGLErrorMessage(); 53 | element.id = id; 54 | 55 | parent.appendChild( element ); 56 | 57 | } 58 | 59 | }; 60 | -------------------------------------------------------------------------------- /example/simpleviewer/public/javascripts/ShaderExtras.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * @author zz85 / http://www.lab4games.net/zz85/blog 4 | * 5 | * ShaderExtras currently contains: 6 | * 7 | * screen 8 | * convolution 9 | * film 10 | * bokeh 11 | * sepia 12 | * dotscreen 13 | * vignette 14 | * bleachbypass 15 | * basic 16 | * dofmipmap 17 | * focus 18 | * triangleBlur 19 | * horizontalBlur + verticalBlur 20 | * horizontalTiltShift + verticalTiltShift 21 | * blend 22 | * fxaa 23 | * luminosity 24 | * colorCorrection 25 | * normalmap 26 | * ssao 27 | * colorify 28 | * unpackDepthRGBA 29 | */ 30 | 31 | THREE.ShaderExtras = { 32 | 33 | /* ------------------------------------------------------------------------- 34 | // Full-screen textured quad shader 35 | ------------------------------------------------------------------------- */ 36 | 37 | 'screen': { 38 | 39 | uniforms: { 40 | 41 | tDiffuse: { type: "t", value: 0, texture: null }, 42 | opacity: { type: "f", value: 1.0 } 43 | 44 | }, 45 | 46 | vertexShader: [ 47 | 48 | "varying vec2 vUv;", 49 | 50 | "void main() {", 51 | 52 | "vUv = vec2( uv.x, 1.0 - uv.y );", 53 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 54 | 55 | "}" 56 | 57 | ].join("\n"), 58 | 59 | fragmentShader: [ 60 | 61 | "uniform float opacity;", 62 | 63 | "uniform sampler2D tDiffuse;", 64 | 65 | "varying vec2 vUv;", 66 | 67 | "void main() {", 68 | 69 | "vec4 texel = texture2D( tDiffuse, vUv );", 70 | "gl_FragColor = opacity * texel;", 71 | 72 | "}" 73 | 74 | ].join("\n") 75 | 76 | }, 77 | 78 | /* ------------------------------------------------------------------------ 79 | // Convolution shader 80 | // - ported from o3d sample to WebGL / GLSL 81 | // http://o3d.googlecode.com/svn/trunk/samples/convolution.html 82 | ------------------------------------------------------------------------ */ 83 | 84 | 'convolution': { 85 | 86 | uniforms: { 87 | 88 | "tDiffuse" : { type: "t", value: 0, texture: null }, 89 | "uImageIncrement" : { type: "v2", value: new THREE.Vector2( 0.001953125, 0.0 ) }, 90 | "cKernel" : { type: "fv1", value: [] } 91 | 92 | }, 93 | 94 | vertexShader: [ 95 | 96 | //"#define KERNEL_SIZE 25.0", 97 | 98 | "uniform vec2 uImageIncrement;", 99 | 100 | "varying vec2 vUv;", 101 | 102 | "void main() {", 103 | 104 | "vUv = uv - ( ( KERNEL_SIZE - 1.0 ) / 2.0 ) * uImageIncrement;", 105 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 106 | 107 | "}" 108 | 109 | ].join("\n"), 110 | 111 | fragmentShader: [ 112 | 113 | //"#define KERNEL_SIZE 25", 114 | "uniform float cKernel[ KERNEL_SIZE ];", 115 | 116 | "uniform sampler2D tDiffuse;", 117 | "uniform vec2 uImageIncrement;", 118 | 119 | "varying vec2 vUv;", 120 | 121 | "void main() {", 122 | 123 | "vec2 imageCoord = vUv;", 124 | "vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );", 125 | 126 | "for( int i = 0; i < KERNEL_SIZE; i ++ ) {", 127 | 128 | "sum += texture2D( tDiffuse, imageCoord ) * cKernel[ i ];", 129 | "imageCoord += uImageIncrement;", 130 | 131 | "}", 132 | 133 | "gl_FragColor = sum;", 134 | 135 | "}" 136 | 137 | 138 | ].join("\n") 139 | 140 | }, 141 | 142 | /* ------------------------------------------------------------------------- 143 | 144 | // Film grain & scanlines shader 145 | 146 | // - ported from HLSL to WebGL / GLSL 147 | // http://www.truevision3d.com/forums/showcase/staticnoise_colorblackwhite_scanline_shaders-t18698.0.html 148 | 149 | // Screen Space Static Postprocessor 150 | // 151 | // Produces an analogue noise overlay similar to a film grain / TV static 152 | // 153 | // Original implementation and noise algorithm 154 | // Pat 'Hawthorne' Shearon 155 | // 156 | // Optimized scanlines + noise version with intensity scaling 157 | // Georg 'Leviathan' Steinrohder 158 | 159 | // This version is provided under a Creative Commons Attribution 3.0 License 160 | // http://creativecommons.org/licenses/by/3.0/ 161 | ------------------------------------------------------------------------- */ 162 | 163 | 'film': { 164 | 165 | uniforms: { 166 | 167 | tDiffuse: { type: "t", value: 0, texture: null }, 168 | time: { type: "f", value: 0.0 }, 169 | nIntensity: { type: "f", value: 0.5 }, 170 | sIntensity: { type: "f", value: 0.05 }, 171 | sCount: { type: "f", value: 4096 }, 172 | grayscale: { type: "i", value: 1 } 173 | 174 | }, 175 | 176 | vertexShader: [ 177 | 178 | "varying vec2 vUv;", 179 | 180 | "void main() {", 181 | 182 | "vUv = vec2( uv.x, 1.0 - uv.y );", 183 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 184 | 185 | "}" 186 | 187 | ].join("\n"), 188 | 189 | fragmentShader: [ 190 | 191 | // control parameter 192 | "uniform float time;", 193 | 194 | "uniform bool grayscale;", 195 | 196 | // noise effect intensity value (0 = no effect, 1 = full effect) 197 | "uniform float nIntensity;", 198 | 199 | // scanlines effect intensity value (0 = no effect, 1 = full effect) 200 | "uniform float sIntensity;", 201 | 202 | // scanlines effect count value (0 = no effect, 4096 = full effect) 203 | "uniform float sCount;", 204 | 205 | "uniform sampler2D tDiffuse;", 206 | 207 | "varying vec2 vUv;", 208 | 209 | "void main() {", 210 | 211 | // sample the source 212 | "vec4 cTextureScreen = texture2D( tDiffuse, vUv );", 213 | 214 | // make some noise 215 | "float x = vUv.x * vUv.y * time * 1000.0;", 216 | "x = mod( x, 13.0 ) * mod( x, 123.0 );", 217 | "float dx = mod( x, 0.01 );", 218 | 219 | // add noise 220 | "vec3 cResult = cTextureScreen.rgb + cTextureScreen.rgb * clamp( 0.1 + dx * 100.0, 0.0, 1.0 );", 221 | 222 | // get us a sine and cosine 223 | "vec2 sc = vec2( sin( vUv.y * sCount ), cos( vUv.y * sCount ) );", 224 | 225 | // add scanlines 226 | "cResult += cTextureScreen.rgb * vec3( sc.x, sc.y, sc.x ) * sIntensity;", 227 | 228 | // interpolate between source and result by intensity 229 | "cResult = cTextureScreen.rgb + clamp( nIntensity, 0.0,1.0 ) * ( cResult - cTextureScreen.rgb );", 230 | 231 | // convert to grayscale if desired 232 | "if( grayscale ) {", 233 | 234 | "cResult = vec3( cResult.r * 0.3 + cResult.g * 0.59 + cResult.b * 0.11 );", 235 | 236 | "}", 237 | 238 | "gl_FragColor = vec4( cResult, cTextureScreen.a );", 239 | 240 | "}" 241 | 242 | ].join("\n") 243 | 244 | }, 245 | 246 | 247 | /* ------------------------------------------------------------------------- 248 | // Depth-of-field shader with bokeh 249 | // ported from GLSL shader by Martins Upitis 250 | // http://artmartinsh.blogspot.com/2010/02/glsl-lens-blur-filter-with-bokeh.html 251 | ------------------------------------------------------------------------- */ 252 | 253 | 'bokeh' : { 254 | 255 | uniforms: { tColor: { type: "t", value: 0, texture: null }, 256 | tDepth: { type: "t", value: 1, texture: null }, 257 | focus: { type: "f", value: 1.0 }, 258 | aspect: { type: "f", value: 1.0 }, 259 | aperture: { type: "f", value: 0.025 }, 260 | maxblur: { type: "f", value: 1.0 }, 261 | }, 262 | 263 | vertexShader: [ 264 | 265 | "varying vec2 vUv;", 266 | 267 | "void main() {", 268 | 269 | "vUv = vec2( uv.x, 1.0 - uv.y );", 270 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 271 | 272 | "}" 273 | 274 | ].join("\n"), 275 | 276 | fragmentShader: [ 277 | 278 | "varying vec2 vUv;", 279 | 280 | "uniform sampler2D tColor;", 281 | "uniform sampler2D tDepth;", 282 | 283 | "uniform float maxblur;", // max blur amount 284 | "uniform float aperture;", // aperture - bigger values for shallower depth of field 285 | 286 | "uniform float focus;", 287 | "uniform float aspect;", 288 | 289 | "void main() {", 290 | 291 | "vec2 aspectcorrect = vec2( 1.0, aspect );", 292 | 293 | "vec4 depth1 = texture2D( tDepth, vUv );", 294 | 295 | "float factor = depth1.x - focus;", 296 | 297 | "vec2 dofblur = vec2 ( clamp( factor * aperture, -maxblur, maxblur ) );", 298 | 299 | "vec2 dofblur9 = dofblur * 0.9;", 300 | "vec2 dofblur7 = dofblur * 0.7;", 301 | "vec2 dofblur4 = dofblur * 0.4;", 302 | 303 | "vec4 col = vec4( 0.0 );", 304 | 305 | "col += texture2D( tColor, vUv.xy );", 306 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur );", 307 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur );", 308 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur );", 309 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur );", 310 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur );", 311 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur );", 312 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur );", 313 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur );", 314 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur );", 315 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur );", 316 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur );", 317 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur );", 318 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur );", 319 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur );", 320 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur );", 321 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur );", 322 | 323 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur9 );", 324 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur9 );", 325 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur9 );", 326 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur9 );", 327 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur9 );", 328 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur9 );", 329 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur9 );", 330 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur9 );", 331 | 332 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur7 );", 333 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur7 );", 334 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur7 );", 335 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur7 );", 336 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur7 );", 337 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur7 );", 338 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur7 );", 339 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur7 );", 340 | 341 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur4 );", 342 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.4, 0.0 ) * aspectcorrect ) * dofblur4 );", 343 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur4 );", 344 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur4 );", 345 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur4 );", 346 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur4 );", 347 | "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur4 );", 348 | "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur4 );", 349 | 350 | "gl_FragColor = col / 41.0;", 351 | "gl_FragColor.a = 1.0;", 352 | 353 | "}" 354 | 355 | ].join("\n") 356 | 357 | }, 358 | 359 | /* ------------------------------------------------------------------------- 360 | // Depth-of-field shader using mipmaps 361 | // - from Matt Handley @applmak 362 | // - requires power-of-2 sized render target with enabled mipmaps 363 | ------------------------------------------------------------------------- */ 364 | 365 | 'dofmipmap': { 366 | 367 | uniforms: { 368 | 369 | tColor: { type: "t", value: 0, texture: null }, 370 | tDepth: { type: "t", value: 1, texture: null }, 371 | focus: { type: "f", value: 1.0 }, 372 | maxblur: { type: "f", value: 1.0 } 373 | 374 | }, 375 | 376 | vertexShader: [ 377 | 378 | "varying vec2 vUv;", 379 | 380 | "void main() {", 381 | 382 | "vUv = vec2( uv.x, 1.0 - uv.y );", 383 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 384 | 385 | "}" 386 | 387 | ].join("\n"), 388 | 389 | fragmentShader: [ 390 | 391 | "uniform float focus;", 392 | "uniform float maxblur;", 393 | 394 | "uniform sampler2D tColor;", 395 | "uniform sampler2D tDepth;", 396 | 397 | "varying vec2 vUv;", 398 | 399 | "void main() {", 400 | 401 | "vec4 depth = texture2D( tDepth, vUv );", 402 | 403 | "float factor = depth.x - focus;", 404 | 405 | "vec4 col = texture2D( tColor, vUv, 2.0 * maxblur * abs( focus - depth.x ) );", 406 | 407 | "gl_FragColor = col;", 408 | "gl_FragColor.a = 1.0;", 409 | 410 | "}" 411 | 412 | ].join("\n") 413 | 414 | }, 415 | 416 | /* ------------------------------------------------------------------------- 417 | // Sepia tone shader 418 | // - based on glfx.js sepia shader 419 | // https://github.com/evanw/glfx.js 420 | ------------------------------------------------------------------------- */ 421 | 422 | 'sepia': { 423 | 424 | uniforms: { 425 | 426 | tDiffuse: { type: "t", value: 0, texture: null }, 427 | amount: { type: "f", value: 1.0 } 428 | 429 | }, 430 | 431 | vertexShader: [ 432 | 433 | "varying vec2 vUv;", 434 | 435 | "void main() {", 436 | 437 | "vUv = vec2( uv.x, 1.0 - uv.y );", 438 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 439 | 440 | "}" 441 | 442 | ].join("\n"), 443 | 444 | fragmentShader: [ 445 | 446 | "uniform float amount;", 447 | 448 | "uniform sampler2D tDiffuse;", 449 | 450 | "varying vec2 vUv;", 451 | 452 | "void main() {", 453 | 454 | "vec4 color = texture2D( tDiffuse, vUv );", 455 | "vec3 c = color.rgb;", 456 | 457 | "color.r = dot( c, vec3( 1.0 - 0.607 * amount, 0.769 * amount, 0.189 * amount ) );", 458 | "color.g = dot( c, vec3( 0.349 * amount, 1.0 - 0.314 * amount, 0.168 * amount ) );", 459 | "color.b = dot( c, vec3( 0.272 * amount, 0.534 * amount, 1.0 - 0.869 * amount ) );", 460 | 461 | "gl_FragColor = vec4( min( vec3( 1.0 ), color.rgb ), color.a );", 462 | 463 | "}" 464 | 465 | ].join("\n") 466 | 467 | }, 468 | 469 | /* ------------------------------------------------------------------------- 470 | // Dot screen shader 471 | // - based on glfx.js sepia shader 472 | // https://github.com/evanw/glfx.js 473 | ------------------------------------------------------------------------- */ 474 | 475 | 'dotscreen': { 476 | 477 | uniforms: { 478 | 479 | tDiffuse: { type: "t", value: 0, texture: null }, 480 | tSize: { type: "v2", value: new THREE.Vector2( 256, 256 ) }, 481 | center: { type: "v2", value: new THREE.Vector2( 0.5, 0.5 ) }, 482 | angle: { type: "f", value: 1.57 }, 483 | scale: { type: "f", value: 1.0 } 484 | 485 | }, 486 | 487 | vertexShader: [ 488 | 489 | "varying vec2 vUv;", 490 | 491 | "void main() {", 492 | 493 | "vUv = vec2( uv.x, 1.0 - uv.y );", 494 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 495 | 496 | "}" 497 | 498 | ].join("\n"), 499 | 500 | fragmentShader: [ 501 | 502 | "uniform vec2 center;", 503 | "uniform float angle;", 504 | "uniform float scale;", 505 | "uniform vec2 tSize;", 506 | 507 | "uniform sampler2D tDiffuse;", 508 | 509 | "varying vec2 vUv;", 510 | 511 | "float pattern() {", 512 | 513 | "float s = sin( angle ), c = cos( angle );", 514 | 515 | "vec2 tex = vUv * tSize - center;", 516 | "vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale;", 517 | 518 | "return ( sin( point.x ) * sin( point.y ) ) * 4.0;", 519 | 520 | "}", 521 | 522 | "void main() {", 523 | 524 | "vec4 color = texture2D( tDiffuse, vUv );", 525 | 526 | "float average = ( color.r + color.g + color.b ) / 3.0;", 527 | 528 | "gl_FragColor = vec4( vec3( average * 10.0 - 5.0 + pattern() ), color.a );", 529 | 530 | "}" 531 | 532 | ].join("\n") 533 | 534 | }, 535 | 536 | /* ------------------------------------------------------------------------------------------------ 537 | // Vignette shader 538 | // - based on PaintEffect postprocess from ro.me 539 | // http://code.google.com/p/3-dreams-of-black/source/browse/deploy/js/effects/PaintEffect.js 540 | ------------------------------------------------------------------------------------------------ */ 541 | 542 | 'vignette': { 543 | 544 | uniforms: { 545 | 546 | tDiffuse: { type: "t", value: 0, texture: null }, 547 | offset: { type: "f", value: 1.0 }, 548 | darkness: { type: "f", value: 1.0 } 549 | 550 | }, 551 | 552 | vertexShader: [ 553 | 554 | "varying vec2 vUv;", 555 | 556 | "void main() {", 557 | 558 | "vUv = vec2( uv.x, 1.0 - uv.y );", 559 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 560 | 561 | "}" 562 | 563 | ].join("\n"), 564 | 565 | fragmentShader: [ 566 | 567 | "uniform float offset;", 568 | "uniform float darkness;", 569 | 570 | "uniform sampler2D tDiffuse;", 571 | 572 | "varying vec2 vUv;", 573 | 574 | "void main() {", 575 | 576 | // Eskil's vignette 577 | 578 | "vec4 texel = texture2D( tDiffuse, vUv );", 579 | "vec2 uv = ( vUv - vec2( 0.5 ) ) * vec2( offset );", 580 | "gl_FragColor = vec4( mix( texel.rgb, vec3( 1.0 - darkness ), dot( uv, uv ) ), texel.a );", 581 | 582 | /* 583 | // alternative version from glfx.js 584 | // this one makes more "dusty" look (as opposed to "burned") 585 | 586 | "vec4 color = texture2D( tDiffuse, vUv );", 587 | "float dist = distance( vUv, vec2( 0.5 ) );", 588 | "color.rgb *= smoothstep( 0.8, offset * 0.799, dist *( darkness + offset ) );", 589 | "gl_FragColor = color;", 590 | */ 591 | 592 | "}" 593 | 594 | ].join("\n") 595 | 596 | }, 597 | 598 | /* ------------------------------------------------------------------------- 599 | // Bleach bypass shader [http://en.wikipedia.org/wiki/Bleach_bypass] 600 | // - based on Nvidia example 601 | // http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html#post_bleach_bypass 602 | ------------------------------------------------------------------------- */ 603 | 604 | 'bleachbypass': { 605 | 606 | uniforms: { 607 | 608 | tDiffuse: { type: "t", value: 0, texture: null }, 609 | opacity: { type: "f", value: 1.0 } 610 | 611 | }, 612 | 613 | vertexShader: [ 614 | 615 | "varying vec2 vUv;", 616 | 617 | "void main() {", 618 | 619 | "vUv = vec2( uv.x, 1.0 - uv.y );", 620 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 621 | 622 | "}" 623 | 624 | ].join("\n"), 625 | 626 | fragmentShader: [ 627 | 628 | "uniform float opacity;", 629 | 630 | "uniform sampler2D tDiffuse;", 631 | 632 | "varying vec2 vUv;", 633 | 634 | "void main() {", 635 | 636 | "vec4 base = texture2D( tDiffuse, vUv );", 637 | 638 | "vec3 lumCoeff = vec3( 0.25, 0.65, 0.1 );", 639 | "float lum = dot( lumCoeff, base.rgb );", 640 | "vec3 blend = vec3( lum );", 641 | 642 | "float L = min( 1.0, max( 0.0, 10.0 * ( lum - 0.45 ) ) );", 643 | 644 | "vec3 result1 = 2.0 * base.rgb * blend;", 645 | "vec3 result2 = 1.0 - 2.0 * ( 1.0 - blend ) * ( 1.0 - base.rgb );", 646 | 647 | "vec3 newColor = mix( result1, result2, L );", 648 | 649 | "float A2 = opacity * base.a;", 650 | "vec3 mixRGB = A2 * newColor.rgb;", 651 | "mixRGB += ( ( 1.0 - A2 ) * base.rgb );", 652 | 653 | "gl_FragColor = vec4( mixRGB, base.a );", 654 | 655 | "}" 656 | 657 | ].join("\n") 658 | 659 | }, 660 | 661 | /* -------------------------------------------------------------------------------------------------- 662 | // Focus shader 663 | // - based on PaintEffect postprocess from ro.me 664 | // http://code.google.com/p/3-dreams-of-black/source/browse/deploy/js/effects/PaintEffect.js 665 | -------------------------------------------------------------------------------------------------- */ 666 | 667 | 'focus': { 668 | 669 | uniforms : { 670 | 671 | "tDiffuse": { type: "t", value: 0, texture: null }, 672 | "screenWidth": { type: "f", value: 1024 }, 673 | "screenHeight": { type: "f", value: 1024 }, 674 | "sampleDistance": { type: "f", value: 0.94 }, 675 | "waveFactor": { type: "f", value: 0.00125 } 676 | 677 | }, 678 | 679 | vertexShader: [ 680 | 681 | "varying vec2 vUv;", 682 | 683 | "void main() {", 684 | 685 | "vUv = vec2( uv.x, 1.0 - uv.y );", 686 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 687 | 688 | "}" 689 | 690 | ].join("\n"), 691 | 692 | fragmentShader: [ 693 | 694 | "uniform float screenWidth;", 695 | "uniform float screenHeight;", 696 | "uniform float sampleDistance;", 697 | "uniform float waveFactor;", 698 | 699 | "uniform sampler2D tDiffuse;", 700 | 701 | "varying vec2 vUv;", 702 | 703 | "void main() {", 704 | 705 | "vec4 color, org, tmp, add;", 706 | "float sample_dist, f;", 707 | "vec2 vin;", 708 | "vec2 uv = vUv;", 709 | 710 | "add += color = org = texture2D( tDiffuse, uv );", 711 | 712 | "vin = ( uv - vec2( 0.5 ) ) * vec2( 1.4 );", 713 | "sample_dist = dot( vin, vin ) * 2.0;", 714 | 715 | "f = ( waveFactor * 100.0 + sample_dist ) * sampleDistance * 4.0;", 716 | 717 | "vec2 sampleSize = vec2( 1.0 / screenWidth, 1.0 / screenHeight ) * vec2( f );", 718 | 719 | "add += tmp = texture2D( tDiffuse, uv + vec2( 0.111964, 0.993712 ) * sampleSize );", 720 | "if( tmp.b < color.b ) color = tmp;", 721 | 722 | "add += tmp = texture2D( tDiffuse, uv + vec2( 0.846724, 0.532032 ) * sampleSize );", 723 | "if( tmp.b < color.b ) color = tmp;", 724 | 725 | "add += tmp = texture2D( tDiffuse, uv + vec2( 0.943883, -0.330279 ) * sampleSize );", 726 | "if( tmp.b < color.b ) color = tmp;", 727 | 728 | "add += tmp = texture2D( tDiffuse, uv + vec2( 0.330279, -0.943883 ) * sampleSize );", 729 | "if( tmp.b < color.b ) color = tmp;", 730 | 731 | "add += tmp = texture2D( tDiffuse, uv + vec2( -0.532032, -0.846724 ) * sampleSize );", 732 | "if( tmp.b < color.b ) color = tmp;", 733 | 734 | "add += tmp = texture2D( tDiffuse, uv + vec2( -0.993712, -0.111964 ) * sampleSize );", 735 | "if( tmp.b < color.b ) color = tmp;", 736 | 737 | "add += tmp = texture2D( tDiffuse, uv + vec2( -0.707107, 0.707107 ) * sampleSize );", 738 | "if( tmp.b < color.b ) color = tmp;", 739 | 740 | "color = color * vec4( 2.0 ) - ( add / vec4( 8.0 ) );", 741 | "color = color + ( add / vec4( 8.0 ) - color ) * ( vec4( 1.0 ) - vec4( sample_dist * 0.5 ) );", 742 | 743 | "gl_FragColor = vec4( color.rgb * color.rgb * vec3( 0.95 ) + color.rgb, 1.0 );", 744 | 745 | "}" 746 | 747 | 748 | ].join("\n") 749 | }, 750 | 751 | /* ------------------------------------------------------------------------- 752 | // Triangle blur shader 753 | // - based on glfx.js triangle blur shader 754 | // https://github.com/evanw/glfx.js 755 | 756 | // A basic blur filter, which convolves the image with a 757 | // pyramid filter. The pyramid filter is separable and is applied as two 758 | // perpendicular triangle filters. 759 | ------------------------------------------------------------------------- */ 760 | 761 | 'triangleBlur': { 762 | 763 | 764 | uniforms : { 765 | 766 | "texture": { type: "t", value: 0, texture: null }, 767 | "delta": { type: "v2", value:new THREE.Vector2( 1, 1 ) } 768 | 769 | }, 770 | 771 | vertexShader: [ 772 | 773 | "varying vec2 vUv;", 774 | 775 | "void main() {", 776 | 777 | "vUv = vec2( uv.x, 1.0 - uv.y );", 778 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 779 | 780 | "}" 781 | 782 | ].join("\n"), 783 | 784 | fragmentShader: [ 785 | 786 | "#define ITERATIONS 10.0", 787 | 788 | "uniform sampler2D texture;", 789 | "uniform vec2 delta;", 790 | 791 | "varying vec2 vUv;", 792 | 793 | "float random( vec3 scale, float seed ) {", 794 | 795 | // use the fragment position for a different seed per-pixel 796 | 797 | "return fract( sin( dot( gl_FragCoord.xyz + seed, scale ) ) * 43758.5453 + seed );", 798 | 799 | "}", 800 | 801 | "void main() {", 802 | 803 | "vec4 color = vec4( 0.0 );", 804 | 805 | "float total = 0.0;", 806 | 807 | // randomize the lookup values to hide the fixed number of samples 808 | 809 | "float offset = random( vec3( 12.9898, 78.233, 151.7182 ), 0.0 );", 810 | 811 | "for ( float t = -ITERATIONS; t <= ITERATIONS; t ++ ) {", 812 | 813 | "float percent = ( t + offset - 0.5 ) / ITERATIONS;", 814 | "float weight = 1.0 - abs( percent );", 815 | 816 | "color += texture2D( texture, vUv + delta * percent ) * weight;", 817 | "total += weight;", 818 | 819 | "}", 820 | 821 | "gl_FragColor = color / total;", 822 | 823 | "}", 824 | 825 | ].join("\n") 826 | 827 | }, 828 | 829 | /* ------------------------------------------------------------------------- 830 | // Simple test shader 831 | ------------------------------------------------------------------------- */ 832 | 833 | 'basic': { 834 | 835 | uniforms: {}, 836 | 837 | vertexShader: [ 838 | 839 | "void main() {", 840 | 841 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 842 | 843 | "}" 844 | 845 | ].join("\n"), 846 | 847 | fragmentShader: [ 848 | 849 | "void main() {", 850 | 851 | "gl_FragColor = vec4( 1.0, 0.0, 0.0, 0.5 );", 852 | 853 | "}" 854 | 855 | ].join("\n") 856 | 857 | }, 858 | 859 | /* -------------------------------------------------------------------------------------------------- 860 | // Two pass Gaussian blur filter (horizontal and vertical blur shaders) 861 | // - described in http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/ 862 | // and used in http://www.cake23.de/traveling-wavefronts-lit-up.html 863 | // 864 | // - 9 samples per pass 865 | // - standard deviation 2.7 866 | // - "h" and "v" parameters should be set to "1 / width" and "1 / height" 867 | -------------------------------------------------------------------------------------------------- */ 868 | 869 | 'horizontalBlur': { 870 | 871 | uniforms: { 872 | 873 | "tDiffuse": { type: "t", value: 0, texture: null }, 874 | "h": { type: "f", value: 1.0 / 512.0 } 875 | 876 | }, 877 | 878 | vertexShader: [ 879 | 880 | "varying vec2 vUv;", 881 | 882 | "void main() {", 883 | 884 | "vUv = vec2( uv.x, 1.0 - uv.y );", 885 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 886 | 887 | "}" 888 | 889 | ].join("\n"), 890 | 891 | fragmentShader: [ 892 | 893 | "uniform sampler2D tDiffuse;", 894 | "uniform float h;", 895 | 896 | "varying vec2 vUv;", 897 | 898 | "void main() {", 899 | 900 | "vec4 sum = vec4( 0.0 );", 901 | 902 | "sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * h, vUv.y ) ) * 0.051;", 903 | "sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * h, vUv.y ) ) * 0.0918;", 904 | "sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * h, vUv.y ) ) * 0.12245;", 905 | "sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * h, vUv.y ) ) * 0.1531;", 906 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", 907 | "sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * h, vUv.y ) ) * 0.1531;", 908 | "sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * h, vUv.y ) ) * 0.12245;", 909 | "sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * h, vUv.y ) ) * 0.0918;", 910 | "sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * h, vUv.y ) ) * 0.051;", 911 | 912 | "gl_FragColor = sum;", 913 | 914 | "}" 915 | 916 | 917 | ].join("\n") 918 | 919 | }, 920 | 921 | 'verticalBlur': { 922 | 923 | uniforms: { 924 | 925 | "tDiffuse": { type: "t", value: 0, texture: null }, 926 | "v": { type: "f", value: 1.0 / 512.0 } 927 | 928 | }, 929 | 930 | vertexShader: [ 931 | 932 | "varying vec2 vUv;", 933 | 934 | "void main() {", 935 | 936 | "vUv = vec2( uv.x, 1.0 - uv.y );", 937 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 938 | 939 | "}" 940 | 941 | ].join("\n"), 942 | 943 | fragmentShader: [ 944 | 945 | "uniform sampler2D tDiffuse;", 946 | "uniform float v;", 947 | 948 | "varying vec2 vUv;", 949 | 950 | "void main() {", 951 | 952 | "vec4 sum = vec4( 0.0 );", 953 | 954 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * v ) ) * 0.051;", 955 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * v ) ) * 0.0918;", 956 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * v ) ) * 0.12245;", 957 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * v ) ) * 0.1531;", 958 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", 959 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * v ) ) * 0.1531;", 960 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * v ) ) * 0.12245;", 961 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * v ) ) * 0.0918;", 962 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * v ) ) * 0.051;", 963 | 964 | "gl_FragColor = sum;", 965 | 966 | "}" 967 | 968 | 969 | ].join("\n") 970 | 971 | }, 972 | 973 | /* -------------------------------------------------------------------------------------------------- 974 | // Simple fake tilt-shift effect, modulating two pass Gaussian blur (see above) by vertical position 975 | // 976 | // - 9 samples per pass 977 | // - standard deviation 2.7 978 | // - "h" and "v" parameters should be set to "1 / width" and "1 / height" 979 | // - "r" parameter control where "focused" horizontal line lies 980 | -------------------------------------------------------------------------------------------------- */ 981 | 982 | 'horizontalTiltShift': { 983 | 984 | uniforms: { 985 | 986 | "tDiffuse": { type: "t", value: 0, texture: null }, 987 | "h": { type: "f", value: 1.0 / 512.0 }, 988 | "r": { type: "f", value: 0.35 } 989 | 990 | }, 991 | 992 | vertexShader: [ 993 | 994 | "varying vec2 vUv;", 995 | 996 | "void main() {", 997 | 998 | "vUv = vec2( uv.x, 1.0 - uv.y );", 999 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 1000 | 1001 | "}" 1002 | 1003 | ].join("\n"), 1004 | 1005 | fragmentShader: [ 1006 | 1007 | "uniform sampler2D tDiffuse;", 1008 | "uniform float h;", 1009 | "uniform float r;", 1010 | 1011 | "varying vec2 vUv;", 1012 | 1013 | "void main() {", 1014 | 1015 | "vec4 sum = vec4( 0.0 );", 1016 | 1017 | "float hh = h * abs( r - vUv.y );", 1018 | 1019 | "sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * hh, vUv.y ) ) * 0.051;", 1020 | "sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * hh, vUv.y ) ) * 0.0918;", 1021 | "sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * hh, vUv.y ) ) * 0.12245;", 1022 | "sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * hh, vUv.y ) ) * 0.1531;", 1023 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", 1024 | "sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * hh, vUv.y ) ) * 0.1531;", 1025 | "sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * hh, vUv.y ) ) * 0.12245;", 1026 | "sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * hh, vUv.y ) ) * 0.0918;", 1027 | "sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * hh, vUv.y ) ) * 0.051;", 1028 | 1029 | "gl_FragColor = sum;", 1030 | 1031 | "}" 1032 | 1033 | 1034 | ].join("\n") 1035 | 1036 | }, 1037 | 1038 | 'verticalTiltShift': { 1039 | 1040 | uniforms: { 1041 | 1042 | "tDiffuse": { type: "t", value: 0, texture: null }, 1043 | "v": { type: "f", value: 1.0 / 512.0 }, 1044 | "r": { type: "f", value: 0.35 } 1045 | 1046 | }, 1047 | 1048 | vertexShader: [ 1049 | 1050 | "varying vec2 vUv;", 1051 | 1052 | "void main() {", 1053 | 1054 | "vUv = vec2( uv.x, 1.0 - uv.y );", 1055 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 1056 | 1057 | "}" 1058 | 1059 | ].join("\n"), 1060 | 1061 | fragmentShader: [ 1062 | 1063 | "uniform sampler2D tDiffuse;", 1064 | "uniform float v;", 1065 | "uniform float r;", 1066 | 1067 | "varying vec2 vUv;", 1068 | 1069 | "void main() {", 1070 | 1071 | "vec4 sum = vec4( 0.0 );", 1072 | 1073 | "float vv = v * abs( r - vUv.y );", 1074 | 1075 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * vv ) ) * 0.051;", 1076 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * vv ) ) * 0.0918;", 1077 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * vv ) ) * 0.12245;", 1078 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * vv ) ) * 0.1531;", 1079 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", 1080 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * vv ) ) * 0.1531;", 1081 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * vv ) ) * 0.12245;", 1082 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * vv ) ) * 0.0918;", 1083 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * vv ) ) * 0.051;", 1084 | 1085 | "gl_FragColor = sum;", 1086 | 1087 | "}" 1088 | 1089 | 1090 | ].join("\n") 1091 | 1092 | }, 1093 | 1094 | /* ------------------------------------------------------------------------- 1095 | // Blend two textures 1096 | ------------------------------------------------------------------------- */ 1097 | 1098 | 'blend': { 1099 | 1100 | uniforms: { 1101 | 1102 | tDiffuse1: { type: "t", value: 0, texture: null }, 1103 | tDiffuse2: { type: "t", value: 1, texture: null }, 1104 | mixRatio: { type: "f", value: 0.5 }, 1105 | opacity: { type: "f", value: 1.0 } 1106 | 1107 | }, 1108 | 1109 | vertexShader: [ 1110 | 1111 | "varying vec2 vUv;", 1112 | 1113 | "void main() {", 1114 | 1115 | "vUv = vec2( uv.x, 1.0 - uv.y );", 1116 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 1117 | 1118 | "}" 1119 | 1120 | ].join("\n"), 1121 | 1122 | fragmentShader: [ 1123 | 1124 | "uniform float opacity;", 1125 | "uniform float mixRatio;", 1126 | 1127 | "uniform sampler2D tDiffuse1;", 1128 | "uniform sampler2D tDiffuse2;", 1129 | 1130 | "varying vec2 vUv;", 1131 | 1132 | "void main() {", 1133 | 1134 | "vec4 texel1 = texture2D( tDiffuse1, vUv );", 1135 | "vec4 texel2 = texture2D( tDiffuse2, vUv );", 1136 | "gl_FragColor = opacity * mix( texel1, texel2, mixRatio );", 1137 | 1138 | "}" 1139 | 1140 | ].join("\n") 1141 | 1142 | }, 1143 | 1144 | /* ------------------------------------------------------------------------- 1145 | // NVIDIA FXAA by Timothy Lottes 1146 | // http://timothylottes.blogspot.com/2011/06/fxaa3-source-released.html 1147 | // - WebGL port by @supereggbert 1148 | // http://www.glge.org/demos/fxaa/ 1149 | ------------------------------------------------------------------------- */ 1150 | 1151 | 'fxaa': { 1152 | 1153 | uniforms: { 1154 | 1155 | "tDiffuse": { type: "t", value: 0, texture: null }, 1156 | "resolution": { type: "v2", value: new THREE.Vector2( 1 / 1024, 1 / 512 ) } 1157 | 1158 | }, 1159 | 1160 | vertexShader: [ 1161 | 1162 | "varying vec2 vUv;", 1163 | 1164 | "void main() {", 1165 | 1166 | "vUv = vec2( uv.x, 1.0 - uv.y );", 1167 | 1168 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 1169 | 1170 | "}" 1171 | 1172 | ].join("\n"), 1173 | 1174 | fragmentShader: [ 1175 | 1176 | "uniform sampler2D tDiffuse;", 1177 | "uniform vec2 resolution;", 1178 | 1179 | "varying vec2 vUv;", 1180 | 1181 | "#define FXAA_REDUCE_MIN (1.0/128.0)", 1182 | "#define FXAA_REDUCE_MUL (1.0/8.0)", 1183 | "#define FXAA_SPAN_MAX 8.0", 1184 | 1185 | "void main() {", 1186 | 1187 | "vec3 rgbNW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ).xyz;", 1188 | "vec3 rgbNE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ).xyz;", 1189 | "vec3 rgbSW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ).xyz;", 1190 | "vec3 rgbSE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ).xyz;", 1191 | "vec3 rgbM = texture2D( tDiffuse, gl_FragCoord.xy * resolution ).xyz;", 1192 | 1193 | "vec3 luma = vec3( 0.299, 0.587, 0.114 );", 1194 | 1195 | "float lumaNW = dot( rgbNW, luma );", 1196 | "float lumaNE = dot( rgbNE, luma );", 1197 | "float lumaSW = dot( rgbSW, luma );", 1198 | "float lumaSE = dot( rgbSE, luma );", 1199 | "float lumaM = dot( rgbM, luma );", 1200 | "float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );", 1201 | "float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );", 1202 | 1203 | "vec2 dir;", 1204 | "dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));", 1205 | "dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));", 1206 | 1207 | "float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );", 1208 | 1209 | "float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );", 1210 | "dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),", 1211 | "max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),", 1212 | "dir * rcpDirMin)) * resolution;", 1213 | 1214 | "vec3 rgbA = 0.5 * (", 1215 | "texture2D( tDiffuse, gl_FragCoord.xy * resolution + dir * ( 1.0 / 3.0 - 0.5 ) ).xyz +", 1216 | "texture2D( tDiffuse, gl_FragCoord.xy * resolution + dir * ( 2.0 / 3.0 - 0.5 ) ).xyz );", 1217 | 1218 | "vec3 rgbB = rgbA * 0.5 + 0.25 * (", 1219 | "texture2D( tDiffuse, gl_FragCoord.xy * resolution + dir * -0.5 ).xyz +", 1220 | "texture2D( tDiffuse, gl_FragCoord.xy * resolution + dir * 0.5 ).xyz );", 1221 | 1222 | "float lumaB = dot( rgbB, luma );", 1223 | 1224 | "if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) {", 1225 | 1226 | "gl_FragColor = vec4( rgbA, 1.0 );", 1227 | 1228 | "} else {", 1229 | 1230 | "gl_FragColor = vec4( rgbB, 1.0 );", 1231 | 1232 | "}", 1233 | 1234 | "}", 1235 | 1236 | ].join("\n"), 1237 | 1238 | }, 1239 | 1240 | /* ------------------------------------------------------------------------- 1241 | // Luminosity 1242 | // http://en.wikipedia.org/wiki/Luminosity 1243 | ------------------------------------------------------------------------- */ 1244 | 1245 | 'luminosity': { 1246 | 1247 | uniforms: { 1248 | 1249 | "tDiffuse": { type: "t", value: 0, texture: null } 1250 | 1251 | }, 1252 | 1253 | vertexShader: [ 1254 | 1255 | "varying vec2 vUv;", 1256 | 1257 | "void main() {", 1258 | 1259 | "vUv = vec2( uv.x, 1.0 - uv.y );", 1260 | 1261 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 1262 | 1263 | "}" 1264 | 1265 | ].join("\n"), 1266 | 1267 | fragmentShader: [ 1268 | 1269 | "uniform sampler2D tDiffuse;", 1270 | 1271 | "varying vec2 vUv;", 1272 | 1273 | "void main() {", 1274 | 1275 | "vec4 texel = texture2D( tDiffuse, vUv );", 1276 | 1277 | "vec3 luma = vec3( 0.299, 0.587, 0.114 );", 1278 | 1279 | "float v = dot( texel.xyz, luma );", 1280 | 1281 | "gl_FragColor = vec4( v, v, v, texel.w );", 1282 | 1283 | "}" 1284 | 1285 | ].join("\n") 1286 | 1287 | }, 1288 | 1289 | /* ------------------------------------------------------------------------- 1290 | // Color correction 1291 | ------------------------------------------------------------------------- */ 1292 | 1293 | 'colorCorrection': { 1294 | 1295 | uniforms: { 1296 | 1297 | "tDiffuse" : { type: "t", value: 0, texture: null }, 1298 | "powRGB" : { type: "v3", value: new THREE.Vector3( 2, 2, 2 ) }, 1299 | "mulRGB" : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) } 1300 | 1301 | }, 1302 | 1303 | vertexShader: [ 1304 | 1305 | "varying vec2 vUv;", 1306 | 1307 | "void main() {", 1308 | 1309 | "vUv = vec2( uv.x, 1.0 - uv.y );", 1310 | 1311 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 1312 | 1313 | "}" 1314 | 1315 | ].join("\n"), 1316 | 1317 | fragmentShader: [ 1318 | 1319 | "uniform sampler2D tDiffuse;", 1320 | "uniform vec3 powRGB;", 1321 | "uniform vec3 mulRGB;", 1322 | 1323 | "varying vec2 vUv;", 1324 | 1325 | "void main() {", 1326 | 1327 | "gl_FragColor = texture2D( tDiffuse, vUv );", 1328 | "gl_FragColor.rgb = mulRGB * pow( gl_FragColor.rgb, powRGB );", 1329 | 1330 | "}" 1331 | 1332 | ].join("\n") 1333 | 1334 | }, 1335 | 1336 | /* ------------------------------------------------------------------------- 1337 | // Normal map shader 1338 | // - compute normals from heightmap 1339 | ------------------------------------------------------------------------- */ 1340 | 1341 | 'normalmap': { 1342 | 1343 | uniforms: { 1344 | 1345 | "heightMap" : { type: "t", value: 0, texture: null }, 1346 | "resolution": { type: "v2", value: new THREE.Vector2( 512, 512 ) }, 1347 | "scale" : { type: "v2", value: new THREE.Vector2( 1, 1 ) }, 1348 | "height" : { type: "f", value: 0.05 } 1349 | 1350 | }, 1351 | 1352 | vertexShader: [ 1353 | 1354 | "varying vec2 vUv;", 1355 | 1356 | "void main() {", 1357 | 1358 | "vUv = vec2( uv.x, 1.0 - uv.y );", 1359 | 1360 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 1361 | 1362 | "}" 1363 | 1364 | ].join("\n"), 1365 | 1366 | fragmentShader: [ 1367 | 1368 | "uniform float height;", 1369 | "uniform vec2 resolution;", 1370 | "uniform sampler2D heightMap;", 1371 | 1372 | "varying vec2 vUv;", 1373 | 1374 | "void main() {", 1375 | 1376 | "float val = texture2D( heightMap, vUv ).x;", 1377 | 1378 | "float valU = texture2D( heightMap, vUv + vec2( 1.0 / resolution.x, 0.0 ) ).x;", 1379 | "float valV = texture2D( heightMap, vUv + vec2( 0.0, 1.0 / resolution.y ) ).x;", 1380 | 1381 | "gl_FragColor = vec4( ( 0.5 * normalize( vec3( val - valU, val - valV, height ) ) + 0.5 ), 1.0 );", 1382 | 1383 | "}", 1384 | 1385 | ].join("\n") 1386 | 1387 | }, 1388 | 1389 | /* ------------------------------------------------------------------------- 1390 | // Screen-space ambient occlusion shader 1391 | // - ported from 1392 | // SSAO GLSL shader v1.2 1393 | // assembled by Martins Upitis (martinsh) (http://devlog-martinsh.blogspot.com) 1394 | // original technique is made by ArKano22 (http://www.gamedev.net/topic/550699-ssao-no-halo-artifacts/) 1395 | // - modifications 1396 | // - modified to use RGBA packed depth texture (use clear color 1,1,1,1 for depth pass) 1397 | // - made fog more compatible with three.js linear fog 1398 | // - refactoring and optimizations 1399 | ------------------------------------------------------------------------- */ 1400 | 1401 | 'ssao': { 1402 | 1403 | uniforms: { 1404 | 1405 | "tDiffuse": { type: "t", value: 0, texture: null }, 1406 | "tDepth": { type: "t", value: 1, texture: null }, 1407 | "size": { type: "v2", value: new THREE.Vector2( 512, 512 ) }, 1408 | "cameraNear": { type: "f", value: 1 }, 1409 | "cameraFar": { type: "f", value: 100 }, 1410 | "fogNear": { type: "f", value: 5 }, 1411 | "fogFar": { type: "f", value: 100 }, 1412 | "fogEnabled": { type: "i", value: 0 }, 1413 | "aoClamp": { type: "f", value: 0.3 } 1414 | 1415 | }, 1416 | 1417 | vertexShader: [ 1418 | 1419 | "varying vec2 vUv;", 1420 | 1421 | "void main() {", 1422 | 1423 | "vUv = vec2( uv.x, 1.0 - uv.y );", 1424 | 1425 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 1426 | 1427 | "}" 1428 | 1429 | ].join("\n"), 1430 | 1431 | fragmentShader: [ 1432 | 1433 | "uniform float cameraNear;", 1434 | "uniform float cameraFar;", 1435 | 1436 | "uniform float fogNear;", 1437 | "uniform float fogFar;", 1438 | 1439 | "uniform bool fogEnabled;", 1440 | 1441 | "uniform vec2 size;", // texture width, height 1442 | "uniform float aoClamp;", // depth clamp - reduces haloing at screen edges 1443 | 1444 | "uniform sampler2D tDiffuse;", 1445 | "uniform sampler2D tDepth;", 1446 | 1447 | "varying vec2 vUv;", 1448 | 1449 | //"#define PI 3.14159265", 1450 | "#define DL 2.399963229728653", // PI * ( 3.0 - sqrt( 5.0 ) ) 1451 | "#define EULER 2.718281828459045", 1452 | 1453 | // helpers 1454 | 1455 | "float width = size.x;", // texture width 1456 | "float height = size.y;", // texture height 1457 | 1458 | "float cameraFarPlusNear = cameraFar + cameraNear;", 1459 | "float cameraFarMinusNear = cameraFar - cameraNear;", 1460 | "float cameraCoef = 2.0 * cameraNear;", 1461 | 1462 | // user variables 1463 | 1464 | "const int samples = 8;", // ao sample count 1465 | "const float radius = 5.0;", // ao radius 1466 | 1467 | "const bool useNoise = false;", // use noise instead of pattern for sample dithering 1468 | "const float noiseAmount = 0.0002;", // dithering amount 1469 | 1470 | "const float diffArea = 0.4;", // self-shadowing reduction 1471 | "const float gDisplace = 0.4;", // gauss bell center 1472 | 1473 | "const bool onlyAO = false;", // use only ambient occlusion pass? 1474 | "const float lumInfluence = 0.3;", // how much luminance affects occlusion 1475 | 1476 | // RGBA depth 1477 | 1478 | "float unpackDepth( const in vec4 rgba_depth ) {", 1479 | 1480 | "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 );", 1481 | "float depth = dot( rgba_depth, bit_shift );", 1482 | "return depth;", 1483 | 1484 | "}", 1485 | 1486 | // generating noise / pattern texture for dithering 1487 | 1488 | "vec2 rand( const vec2 coord ) {", 1489 | 1490 | "vec2 noise;", 1491 | 1492 | "if ( useNoise ) {", 1493 | 1494 | "float nx = dot ( coord, vec2( 12.9898, 78.233 ) );", 1495 | "float ny = dot ( coord, vec2( 12.9898, 78.233 ) * 2.0 );", 1496 | 1497 | "noise = clamp( fract ( 43758.5453 * sin( vec2( nx, ny ) ) ), 0.0, 1.0 );", 1498 | 1499 | "} else {", 1500 | 1501 | "float ff = fract( 1.0 - coord.s * ( width / 2.0 ) );", 1502 | "float gg = fract( coord.t * ( height / 2.0 ) );", 1503 | 1504 | "noise = vec2( 0.25, 0.75 ) * vec2( ff ) + vec2( 0.75, 0.25 ) * gg;", 1505 | 1506 | "}", 1507 | 1508 | "return ( noise * 2.0 - 1.0 ) * noiseAmount;", 1509 | 1510 | "}", 1511 | 1512 | "float doFog() {", 1513 | 1514 | "float zdepth = unpackDepth( texture2D( tDepth, vUv ) );", 1515 | "float depth = -cameraFar * cameraNear / ( zdepth * cameraFarMinusNear - cameraFar );", 1516 | 1517 | "return smoothstep( fogNear, fogFar, depth );", 1518 | 1519 | "}", 1520 | 1521 | "float readDepth( const in vec2 coord ) {", 1522 | 1523 | //"return ( 2.0 * cameraNear ) / ( cameraFar + cameraNear - unpackDepth( texture2D( tDepth, coord ) ) * ( cameraFar - cameraNear ) );", 1524 | "return cameraCoef / ( cameraFarPlusNear - unpackDepth( texture2D( tDepth, coord ) ) * cameraFarMinusNear );", 1525 | 1526 | 1527 | "}", 1528 | 1529 | "float compareDepths( const in float depth1, const in float depth2, inout int far ) {", 1530 | 1531 | "float garea = 2.0;", // gauss bell width 1532 | "float diff = ( depth1 - depth2 ) * 100.0;", // depth difference (0-100) 1533 | 1534 | // reduce left bell width to avoid self-shadowing 1535 | 1536 | "if ( diff < gDisplace ) {", 1537 | 1538 | "garea = diffArea;", 1539 | 1540 | "} else {", 1541 | 1542 | "far = 1;", 1543 | 1544 | "}", 1545 | 1546 | "float dd = diff - gDisplace;", 1547 | "float gauss = pow( EULER, -2.0 * dd * dd / ( garea * garea ) );", 1548 | "return gauss;", 1549 | 1550 | "}", 1551 | 1552 | "float calcAO( float depth, float dw, float dh ) {", 1553 | 1554 | "float dd = radius - depth * radius;", 1555 | "vec2 vv = vec2( dw, dh );", 1556 | 1557 | "vec2 coord1 = vUv + dd * vv;", 1558 | "vec2 coord2 = vUv - dd * vv;", 1559 | 1560 | "float temp1 = 0.0;", 1561 | "float temp2 = 0.0;", 1562 | 1563 | "int far = 0;", 1564 | "temp1 = compareDepths( depth, readDepth( coord1 ), far );", 1565 | 1566 | // DEPTH EXTRAPOLATION 1567 | 1568 | "if ( far > 0 ) {", 1569 | 1570 | "temp2 = compareDepths( readDepth( coord2 ), depth, far );", 1571 | "temp1 += ( 1.0 - temp1 ) * temp2;", 1572 | 1573 | "}", 1574 | 1575 | "return temp1;", 1576 | 1577 | "}", 1578 | 1579 | "void main() {", 1580 | 1581 | "vec2 noise = rand( vUv );", 1582 | "float depth = readDepth( vUv );", 1583 | 1584 | "float tt = clamp( depth, aoClamp, 1.0 );", 1585 | 1586 | "float w = ( 1.0 / width ) / tt + ( noise.x * ( 1.0 - noise.x ) );", 1587 | "float h = ( 1.0 / height ) / tt + ( noise.y * ( 1.0 - noise.y ) );", 1588 | 1589 | "float pw;", 1590 | "float ph;", 1591 | 1592 | "float ao;", 1593 | 1594 | "float dz = 1.0 / float( samples );", 1595 | "float z = 1.0 - dz / 2.0;", 1596 | "float l = 0.0;", 1597 | 1598 | "for ( int i = 0; i <= samples; i ++ ) {", 1599 | 1600 | "float r = sqrt( 1.0 - z );", 1601 | 1602 | "pw = cos( l ) * r;", 1603 | "ph = sin( l ) * r;", 1604 | "ao += calcAO( depth, pw * w, ph * h );", 1605 | "z = z - dz;", 1606 | "l = l + DL;", 1607 | 1608 | "}", 1609 | 1610 | "ao /= float( samples );", 1611 | "ao = 1.0 - ao;", 1612 | 1613 | "if ( fogEnabled ) {", 1614 | 1615 | "ao = mix( ao, 1.0, doFog() );", 1616 | 1617 | "}", 1618 | 1619 | "vec3 color = texture2D( tDiffuse, vUv ).rgb;", 1620 | 1621 | "vec3 lumcoeff = vec3( 0.299, 0.587, 0.114 );", 1622 | "float lum = dot( color.rgb, lumcoeff );", 1623 | "vec3 luminance = vec3( lum );", 1624 | 1625 | "vec3 final = vec3( color * mix( vec3( ao ), vec3( 1.0 ), luminance * lumInfluence ) );", // mix( color * ao, white, luminance ) 1626 | 1627 | "if ( onlyAO ) {", 1628 | 1629 | "final = vec3( mix( vec3( ao ), vec3( 1.0 ), luminance * lumInfluence ) );", // ambient occlusion only 1630 | 1631 | "}", 1632 | 1633 | "gl_FragColor = vec4( final, 1.0 );", 1634 | 1635 | "}" 1636 | 1637 | ].join("\n") 1638 | 1639 | }, 1640 | 1641 | /* ------------------------------------------------------------------------- 1642 | // Colorify shader 1643 | ------------------------------------------------------------------------- */ 1644 | 1645 | 'colorify': { 1646 | 1647 | uniforms: { 1648 | 1649 | tDiffuse: { type: "t", value: 0, texture: null }, 1650 | color: { type: "c", value: new THREE.Color( 0xffffff ) } 1651 | 1652 | }, 1653 | 1654 | vertexShader: [ 1655 | 1656 | "varying vec2 vUv;", 1657 | 1658 | "void main() {", 1659 | 1660 | "vUv = vec2( uv.x, 1.0 - uv.y );", 1661 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 1662 | 1663 | "}" 1664 | 1665 | ].join("\n"), 1666 | 1667 | fragmentShader: [ 1668 | 1669 | "uniform vec3 color;", 1670 | "uniform sampler2D tDiffuse;", 1671 | 1672 | "varying vec2 vUv;", 1673 | 1674 | "void main() {", 1675 | 1676 | "vec4 texel = texture2D( tDiffuse, vUv );", 1677 | 1678 | "vec3 luma = vec3( 0.299, 0.587, 0.114 );", 1679 | "float v = dot( texel.xyz, luma );", 1680 | 1681 | "gl_FragColor = vec4( v * color, texel.w );", 1682 | 1683 | "}" 1684 | 1685 | ].join("\n") 1686 | 1687 | }, 1688 | 1689 | /* ------------------------------------------------------------------------- 1690 | // Unpack RGBA depth shader 1691 | // - show RGBA encoded depth as monochrome color 1692 | ------------------------------------------------------------------------- */ 1693 | 1694 | 'unpackDepthRGBA': { 1695 | 1696 | uniforms: { 1697 | 1698 | tDiffuse: { type: "t", value: 0, texture: null }, 1699 | opacity: { type: "f", value: 1.0 } 1700 | 1701 | }, 1702 | 1703 | vertexShader: [ 1704 | 1705 | "varying vec2 vUv;", 1706 | 1707 | "void main() {", 1708 | 1709 | "vUv = vec2( uv.x, 1.0 - uv.y );", 1710 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 1711 | 1712 | "}" 1713 | 1714 | ].join("\n"), 1715 | 1716 | fragmentShader: [ 1717 | 1718 | "uniform float opacity;", 1719 | 1720 | "uniform sampler2D tDiffuse;", 1721 | 1722 | "varying vec2 vUv;", 1723 | 1724 | // RGBA depth 1725 | 1726 | "float unpackDepth( const in vec4 rgba_depth ) {", 1727 | 1728 | "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 );", 1729 | "float depth = dot( rgba_depth, bit_shift );", 1730 | "return depth;", 1731 | 1732 | "}", 1733 | 1734 | "void main() {", 1735 | 1736 | "float depth = 1.0 - unpackDepth( texture2D( tDiffuse, vUv ) );", 1737 | "gl_FragColor = opacity * vec4( vec3( depth ), 1.0 );", 1738 | 1739 | "}" 1740 | 1741 | ].join("\n") 1742 | 1743 | }, 1744 | 1745 | // METHODS 1746 | 1747 | buildKernel: function( sigma ) { 1748 | 1749 | // We lop off the sqrt(2 * pi) * sigma term, since we're going to normalize anyway. 1750 | 1751 | function gauss( x, sigma ) { 1752 | 1753 | return Math.exp( - ( x * x ) / ( 2.0 * sigma * sigma ) ); 1754 | 1755 | } 1756 | 1757 | var i, values, sum, halfWidth, kMaxKernelSize = 25, kernelSize = 2 * Math.ceil( sigma * 3.0 ) + 1; 1758 | 1759 | if ( kernelSize > kMaxKernelSize ) kernelSize = kMaxKernelSize; 1760 | halfWidth = ( kernelSize - 1 ) * 0.5 1761 | 1762 | values = new Array( kernelSize ); 1763 | sum = 0.0; 1764 | for ( i = 0; i < kernelSize; ++i ) { 1765 | 1766 | values[ i ] = gauss( i - halfWidth, sigma ); 1767 | sum += values[ i ]; 1768 | 1769 | } 1770 | 1771 | // normalize the kernel 1772 | 1773 | for ( i = 0; i < kernelSize; ++i ) values[ i ] /= sum; 1774 | 1775 | return values; 1776 | 1777 | } 1778 | 1779 | }; 1780 | -------------------------------------------------------------------------------- /example/simpleviewer/public/javascripts/Stats.js: -------------------------------------------------------------------------------- 1 | // stats.js r8 - http://github.com/mrdoob/stats.js 2 | var Stats=function(){var h,a,n=0,o=0,i=Date.now(),u=i,p=i,l=0,q=1E3,r=0,e,j,f,b=[[16,16,48],[0,255,255]],m=0,s=1E3,t=0,d,k,g,c=[[16,48,16],[0,255,0]];h=document.createElement("div");h.style.cursor="pointer";h.style.width="80px";h.style.opacity="0.9";h.style.zIndex="10001";h.addEventListener("mousedown",function(a){a.preventDefault();n=(n+1)%2;n==0?(e.style.display="block",d.style.display="none"):(e.style.display="none",d.style.display="block")},!1);e=document.createElement("div");e.style.textAlign= 3 | "left";e.style.lineHeight="1.2em";e.style.backgroundColor="rgb("+Math.floor(b[0][0]/2)+","+Math.floor(b[0][1]/2)+","+Math.floor(b[0][2]/2)+")";e.style.padding="0 0 3px 3px";h.appendChild(e);j=document.createElement("div");j.style.fontFamily="Helvetica, Arial, sans-serif";j.style.fontSize="9px";j.style.color="rgb("+b[1][0]+","+b[1][1]+","+b[1][2]+")";j.style.fontWeight="bold";j.innerHTML="FPS";e.appendChild(j);f=document.createElement("div");f.style.position="relative";f.style.width="74px";f.style.height= 4 | "30px";f.style.backgroundColor="rgb("+b[1][0]+","+b[1][1]+","+b[1][2]+")";for(e.appendChild(f);f.children.length<74;)a=document.createElement("span"),a.style.width="1px",a.style.height="30px",a.style.cssFloat="left",a.style.backgroundColor="rgb("+b[0][0]+","+b[0][1]+","+b[0][2]+")",f.appendChild(a);d=document.createElement("div");d.style.textAlign="left";d.style.lineHeight="1.2em";d.style.backgroundColor="rgb("+Math.floor(c[0][0]/2)+","+Math.floor(c[0][1]/2)+","+Math.floor(c[0][2]/2)+")";d.style.padding= 5 | "0 0 3px 3px";d.style.display="none";h.appendChild(d);k=document.createElement("div");k.style.fontFamily="Helvetica, Arial, sans-serif";k.style.fontSize="9px";k.style.color="rgb("+c[1][0]+","+c[1][1]+","+c[1][2]+")";k.style.fontWeight="bold";k.innerHTML="MS";d.appendChild(k);g=document.createElement("div");g.style.position="relative";g.style.width="74px";g.style.height="30px";g.style.backgroundColor="rgb("+c[1][0]+","+c[1][1]+","+c[1][2]+")";for(d.appendChild(g);g.children.length<74;)a=document.createElement("span"), 6 | a.style.width="1px",a.style.height=Math.random()*30+"px",a.style.cssFloat="left",a.style.backgroundColor="rgb("+c[0][0]+","+c[0][1]+","+c[0][2]+")",g.appendChild(a);return{domElement:h,update:function(){i=Date.now();m=i-u;s=Math.min(s,m);t=Math.max(t,m);k.textContent=m+" MS ("+s+"-"+t+")";var a=Math.min(30,30-m/200*30);g.appendChild(g.firstChild).style.height=a+"px";u=i;o++;if(i>p+1E3)l=Math.round(o*1E3/(i-p)),q=Math.min(q,l),r=Math.max(r,l),j.textContent=l+" FPS ("+q+"-"+r+")",a=Math.min(30,30-l/ 7 | 100*30),f.appendChild(f.firstChild).style.height=a+"px",p=i,o=0}}}; 8 | 9 | -------------------------------------------------------------------------------- /example/simpleviewer/public/javascripts/kinect.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | var server, 3 | socket, 4 | host = 'localhost', 5 | port = 3000, 6 | connected = false, 7 | connectionCallback, 8 | commandCallbacks = {}; 9 | 10 | socket = new io.Socket(host, { 11 | port: port, 12 | connectTimeout: 10000, 13 | reconnect: true 14 | }); 15 | 16 | socket.on('connecting', function(transportType) { 17 | connected = false; 18 | console.log('Connecting to %s:%d using %s', host, port, transportType); 19 | }); 20 | 21 | socket.on('connect', function() { 22 | connected = true; 23 | console.log('Connected to %s:%d', host, port); 24 | if (connectionCallback) { 25 | connectionCallback(); 26 | } 27 | }); 28 | 29 | socket.on('connect_failed', function() { 30 | connected = false; 31 | console.log('Connect failed.'); 32 | }); 33 | 34 | socket.on('close', function() { 35 | connected = false; 36 | console.log('Connection closed.'); 37 | }); 38 | 39 | socket.on('disconnect', function() { 40 | connected = false; 41 | console.log('Connection disconnected.'); 42 | }); 43 | 44 | socket.on('recconect', function(transportType, reconnectionAttempts) { 45 | connected = true; 46 | console.log('Reconnecting to %s:%d using %s %s', host, port, transportType, reconnectionAttempts); 47 | }); 48 | 49 | socket.on('reconnect_failed', function() { 50 | connected = false; 51 | console.log('Reconnect failed.'); 52 | }); 53 | 54 | socket.on('message', function(command) { 55 | var cmd = JSON.parse(command); 56 | // console.log('[callback][%s]', cmd.type); 57 | if (commandCallbacks.hasOwnProperty(cmd.type)) { 58 | commandCallbacks[cmd.type].call(Kinect, cmd.result); 59 | }; 60 | }); 61 | 62 | Kinect = { 63 | 64 | connect: function(callback) { 65 | socket.connect(); 66 | if (callback && typeof(callback) === 'function') { 67 | connectionCallback = callback 68 | } 69 | }, 70 | 71 | sendCommand: function(commandType, options) { 72 | if (connected) { 73 | var cmd = options || {}; 74 | cmd.type = commandType 75 | // console.log('[send][%s]', cmd.type, cmd); 76 | socket.send(JSON.stringify(cmd)); 77 | } 78 | }, 79 | 80 | on: function(commandType, callback) { 81 | if (callback && typeof(callback) === 'function') { 82 | commandCallbacks[commandType] = callback; 83 | } 84 | }, 85 | 86 | setLed: function(ledOption) { 87 | this.sendCommand('setLed', { option: ledOption }); 88 | }, 89 | 90 | setTiltAngle: function(angle) { 91 | this.sendCommand('setTiltAngle', { angle: angle }); 92 | }, 93 | 94 | getDepth: function(callback) { 95 | this.sendCommand('getDepth'); 96 | this.on('getDepth', function(ret) { 97 | if (callback) { 98 | callback.call(Kinect, ret.data); 99 | } 100 | }); 101 | }, 102 | 103 | getVideo: function(callback) { 104 | this.sendCommand('getVideo'); 105 | this.on('getVideo', function(ret) { 106 | if (callback) { 107 | callback.call(Kinect, ret.data); 108 | } 109 | }); 110 | }, 111 | 112 | stop: function() { 113 | this.sendCommand('stop'); 114 | } 115 | 116 | }; 117 | 118 | Kinect.LED_OPTIONS = { 119 | OFF: 0, 120 | GREEN: 1, 121 | RED: 2, 122 | YELLOW: 3, 123 | BLINK_GREEN: 5, 124 | BLINK_RED_YELLOW: 6 125 | }; 126 | 127 | return Kinect; 128 | })(this); -------------------------------------------------------------------------------- /example/simpleviewer/public/javascripts/main.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | var rgbButton = $('#rbgButton'), 3 | depthButton = $('#depthButton'), 4 | stopButton = $('#stopButton'), 5 | depthCanvas = document.getElementById('depthbuffer'), 6 | depthContext = depthCanvas.getContext('2d'), 7 | // screenImage = screenContext.createImageData(screenCanvas.width, screenCanvas.height), 8 | depthImage = depthContext.createImageData(80, 60), 9 | depthSize = depthCanvas.width * depthCanvas.height, 10 | 11 | screenCanvas = document.getElementById('screen'), 12 | screenContext = screenCanvas.getContext('2d'), 13 | // screenImage = screenContext.createImageData(screenCanvas.width, screenCanvas.height), 14 | screenImage = screenContext.createImageData(400, 300), 15 | screenSize = screenCanvas.width * screenCanvas.height, 16 | 17 | ledSwitch = $('input[name=led]'), 18 | tiltAngleInput = $('#tiltAngleInput'), 19 | tiltAngleButton = $('#tiltAngleButton'); 20 | 21 | Kinect.connect(); 22 | /* 23 | rgbButton.click(function(e) { 24 | e.preventDefault(); 25 | Kinect.getVideo(function(data) { 26 | var length = data.length, 27 | pixels = screenImage.data, 28 | i, srcIndex, dstIndex; 29 | 30 | console.log(length); 31 | 32 | for (i = 0; i < screenSize; i+=4) { 33 | srcIndex = i * 3; 34 | dstIndex = i * 4; 35 | pixels[dstIndex ] = data[srcIndex ]; 36 | pixels[dstIndex+1] = data[srcIndex+1]; 37 | pixels[dstIndex+2] = data[srcIndex+2]; 38 | pixels[dstIndex+3] = 255; 39 | } 40 | 41 | screenContext.putImageData(screenImage, 0, 0); 42 | }); 43 | }); 44 | */ 45 | 46 | 47 | var last_frametime = 0; 48 | var last_fps = 0; 49 | 50 | var getDepthFrame = function() { 51 | 52 | Kinect.getDepth(function(data) { 53 | console.log(data); 54 | 55 | var offset = 0, 56 | length = data.length, 57 | pixels = depthImage.data, 58 | i, color; 59 | 60 | offset = 0; 61 | for (i = 0; i < length; ++i) { 62 | color = data[i] ; 63 | pixels[offset ] = color; 64 | pixels[offset+1] = color; 65 | pixels[offset+2] = color; 66 | pixels[offset+3] = 255; 67 | offset += 4; 68 | } 69 | depthContext.putImageData(depthImage, 0, 0); 70 | screenContext.drawImage(depthCanvas, 0,0,depthCanvas.width,depthCanvas.height,0,0,screenCanvas.width,screenCanvas.height); 71 | 72 | var t = (new Date()).getTime(); 73 | if (last_frametime == 0) 74 | last_frametime = t; 75 | 76 | var dt = t - last_frametime; 77 | if( dt >0 ){ 78 | var cfps = 1000.0 / dt; 79 | 80 | last_fps *= 0.5; 81 | last_fps += cfps*0.5; 82 | } 83 | 84 | $('#debug').text('avg. fps: '+Math.round(last_fps,3)); 85 | 86 | last_frametime = t; 87 | getDepthFrame(); 88 | }); 89 | }; 90 | 91 | setTimeout(function(){ 92 | getDepthFrame(); 93 | }, 500); 94 | 95 | /* 96 | depthButton.click(function(e) { 97 | e.preventDefault(); 98 | Kinect.getDepth(function(data) { 99 | var offset = 0, 100 | length = data.length, 101 | pixels = screenImage.data, 102 | scale = 255 / 2047, 103 | i, color; 104 | 105 | for (i = 0; i < length; ++i) { 106 | offset = 4 * i; 107 | color = data[i] * scale | 0; 108 | pixels[offset ] = color; 109 | pixels[offset+1] = color; 110 | pixels[offset+2] = color; 111 | pixels[offset+3] = 255; 112 | } 113 | 114 | screenContext.putImageData(screenImage, 0, 0); 115 | }); 116 | }); 117 | 118 | stopButton.click(function(e) { 119 | e.preventDefault(); 120 | Kinect.stop(); 121 | }); 122 | */ 123 | ledSwitch.click(function(e) { 124 | Kinect.setLed($(this).val()); 125 | }); 126 | 127 | tiltAngleButton.click(function(e) { 128 | e.preventDefault(); 129 | var v = tiltAngleInput.val(), 130 | angle = parseFloat(v); 131 | if (!isNaN(angle)) { 132 | Kinect.setTiltAngle(angle); 133 | } 134 | }); 135 | 136 | }); 137 | -------------------------------------------------------------------------------- /example/simpleviewer/public/javascripts/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 | // screen material 20 | 21 | var screenShader = THREE.ShaderExtras[ "screen" ]; 22 | 23 | this.screenUniforms = THREE.UniformsUtils.clone( screenShader.uniforms ); 24 | 25 | this.screenUniforms[ "opacity" ].value = strength; 26 | 27 | this.materialScreen = new THREE.ShaderMaterial( { 28 | 29 | uniforms: this.screenUniforms, 30 | vertexShader: screenShader.vertexShader, 31 | fragmentShader: screenShader.fragmentShader, 32 | blending: THREE.AdditiveBlending, 33 | transparent: true 34 | 35 | } ); 36 | 37 | // convolution material 38 | 39 | var convolutionShader = THREE.ShaderExtras[ "convolution" ]; 40 | 41 | this.convolutionUniforms = THREE.UniformsUtils.clone( convolutionShader.uniforms ); 42 | 43 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurx; 44 | this.convolutionUniforms[ "cKernel" ].value = THREE.ShaderExtras.buildKernel( sigma ); 45 | 46 | this.materialConvolution = new THREE.ShaderMaterial( { 47 | 48 | uniforms: this.convolutionUniforms, 49 | vertexShader: "#define KERNEL_SIZE " + kernelSize + ".0\n" + convolutionShader.vertexShader, 50 | fragmentShader: "#define KERNEL_SIZE " + kernelSize + "\n" + convolutionShader.fragmentShader 51 | 52 | } ); 53 | 54 | this.enabled = true; 55 | this.needsSwap = false; 56 | this.clear = false; 57 | 58 | }; 59 | 60 | THREE.BloomPass.prototype = { 61 | 62 | render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { 63 | 64 | if ( maskActive ) renderer.context.disable( renderer.context.STENCIL_TEST ); 65 | 66 | // Render quad with blured scene into texture (convolution pass 1) 67 | 68 | THREE.EffectComposer.quad.material = this.materialConvolution; 69 | 70 | this.convolutionUniforms[ "tDiffuse" ].texture = readBuffer; 71 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurX; 72 | 73 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, this.renderTargetX, true ); 74 | 75 | 76 | // Render quad with blured scene into texture (convolution pass 2) 77 | 78 | this.convolutionUniforms[ "tDiffuse" ].texture = this.renderTargetX; 79 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurY; 80 | 81 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, this.renderTargetY, true ); 82 | 83 | // Render original scene with superimposed blur to texture 84 | 85 | THREE.EffectComposer.quad.material = this.materialScreen; 86 | 87 | this.screenUniforms[ "tDiffuse" ].texture = this.renderTargetY; 88 | 89 | if ( maskActive ) renderer.context.enable( renderer.context.STENCIL_TEST ); 90 | 91 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, readBuffer, this.clear ); 92 | 93 | } 94 | 95 | }; 96 | 97 | THREE.BloomPass.blurX = new THREE.Vector2( 0.001953125, 0.0 ); 98 | THREE.BloomPass.blurY = new THREE.Vector2( 0.0, 0.001953125 ); 99 | 100 | 101 | -------------------------------------------------------------------------------- /example/simpleviewer/public/javascripts/postprocessing/DotScreenPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.DotScreenPass = function( center, angle, scale ) { 6 | 7 | var shader = THREE.ShaderExtras[ "dotscreen" ]; 8 | 9 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 10 | 11 | if ( center !== undefined ) 12 | this.uniforms[ "center" ].value.copy( center ); 13 | 14 | if ( angle !== undefined ) this.uniforms[ "angle"].value = angle; 15 | if ( scale !== undefined ) this.uniforms[ "scale"].value = scale; 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.renderToScreen = false; 27 | this.needsSwap = true; 28 | 29 | }; 30 | 31 | THREE.DotScreenPass.prototype = { 32 | 33 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 34 | 35 | this.uniforms[ "tDiffuse" ].texture = readBuffer; 36 | this.uniforms[ "tSize" ].value.set( readBuffer.width, readBuffer.height ); 37 | 38 | THREE.EffectComposer.quad.material = this.material; 39 | 40 | if ( this.renderToScreen ) { 41 | 42 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera ); 43 | 44 | } else { 45 | 46 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, writeBuffer, false ); 47 | 48 | } 49 | 50 | } 51 | 52 | }; 53 | -------------------------------------------------------------------------------- /example/simpleviewer/public/javascripts/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 | this.renderTarget1 = renderTarget; 10 | 11 | if ( this.renderTarget1 === undefined ) { 12 | 13 | this.renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false }; 14 | this.renderTarget1 = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, this.renderTargetParameters ); 15 | 16 | } 17 | 18 | this.renderTarget2 = this.renderTarget1.clone(); 19 | 20 | this.writeBuffer = this.renderTarget1; 21 | this.readBuffer = this.renderTarget2; 22 | 23 | this.passes = []; 24 | 25 | this.copyPass = new THREE.ShaderPass( THREE.ShaderExtras[ "screen" ] ); 26 | 27 | }; 28 | 29 | THREE.EffectComposer.prototype = { 30 | 31 | swapBuffers: function() { 32 | 33 | var tmp = this.readBuffer; 34 | this.readBuffer = this.writeBuffer; 35 | this.writeBuffer = tmp; 36 | 37 | }, 38 | 39 | addPass: function ( pass ) { 40 | 41 | this.passes.push( pass ); 42 | 43 | }, 44 | 45 | render: function ( delta ) { 46 | 47 | this.writeBuffer = this.renderTarget1; 48 | this.readBuffer = this.renderTarget2; 49 | 50 | var maskActive = false; 51 | 52 | var pass, i, il = this.passes.length; 53 | 54 | for ( i = 0; i < il; i ++ ) { 55 | 56 | pass = this.passes[ i ]; 57 | 58 | if ( !pass.enabled ) continue; 59 | 60 | pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive ); 61 | 62 | if ( pass.needsSwap ) { 63 | 64 | if ( maskActive ) { 65 | 66 | var context = this.renderer.context; 67 | 68 | context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff ); 69 | 70 | this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta ); 71 | 72 | context.stencilFunc( context.EQUAL, 1, 0xffffffff ); 73 | 74 | } 75 | 76 | this.swapBuffers(); 77 | 78 | } 79 | 80 | if ( pass instanceof THREE.MaskPass ) { 81 | 82 | maskActive = true; 83 | 84 | } else if ( pass instanceof THREE.ClearMaskPass ) { 85 | 86 | maskActive = false; 87 | 88 | } 89 | 90 | } 91 | 92 | }, 93 | 94 | reset: function ( renderTarget ) { 95 | 96 | this.renderTarget1 = renderTarget; 97 | 98 | if ( this.renderTarget1 === undefined ) { 99 | 100 | this.renderTarget1 = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, this.renderTargetParameters ); 101 | 102 | } 103 | 104 | this.renderTarget2 = this.renderTarget1.clone(); 105 | 106 | this.writeBuffer = this.renderTarget1; 107 | this.readBuffer = this.renderTarget2; 108 | 109 | THREE.EffectComposer.quad.scale.set( window.innerWidth, window.innerHeight, 1 ); 110 | 111 | THREE.EffectComposer.camera.left = window.innerWidth / - 2; 112 | THREE.EffectComposer.camera.right = window.innerWidth / 2; 113 | THREE.EffectComposer.camera.top = window.innerHeight / 2; 114 | THREE.EffectComposer.camera.bottom = window.innerHeight / - 2; 115 | 116 | THREE.EffectComposer.camera.updateProjectionMatrix(); 117 | 118 | } 119 | 120 | }; 121 | 122 | // shared ortho camera 123 | 124 | THREE.EffectComposer.camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, -10000, 10000 ); 125 | 126 | // shared fullscreen quad scene 127 | 128 | THREE.EffectComposer.geometry = new THREE.PlaneGeometry( 1, 1 ); 129 | 130 | THREE.EffectComposer.quad = new THREE.Mesh( THREE.EffectComposer.geometry, null ); 131 | THREE.EffectComposer.quad.position.z = -100; 132 | THREE.EffectComposer.quad.scale.set( window.innerWidth, window.innerHeight, 1 ); 133 | 134 | THREE.EffectComposer.scene = new THREE.Scene(); 135 | THREE.EffectComposer.scene.add( THREE.EffectComposer.quad ); 136 | THREE.EffectComposer.scene.add( THREE.EffectComposer.camera ); 137 | -------------------------------------------------------------------------------- /example/simpleviewer/public/javascripts/postprocessing/FilmPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.FilmPass = function( noiseIntensity, scanlinesIntensity, scanlinesCount, grayscale ) { 6 | 7 | var shader = THREE.ShaderExtras[ "film" ]; 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 | if ( grayscale !== undefined ) this.uniforms.grayscale.value = grayscale; 20 | if ( noiseIntensity !== undefined ) this.uniforms.nIntensity.value = noiseIntensity; 21 | if ( scanlinesIntensity !== undefined ) this.uniforms.sIntensity.value = scanlinesIntensity; 22 | if ( scanlinesCount !== undefined ) this.uniforms.sCount.value = scanlinesCount; 23 | 24 | this.enabled = true; 25 | this.renderToScreen = false; 26 | this.needsSwap = true; 27 | 28 | }; 29 | 30 | THREE.FilmPass.prototype = { 31 | 32 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 33 | 34 | this.uniforms[ "tDiffuse" ].texture = readBuffer; 35 | this.uniforms[ "time" ].value += delta; 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, false ); 46 | 47 | } 48 | 49 | } 50 | 51 | }; 52 | -------------------------------------------------------------------------------- /example/simpleviewer/public/javascripts/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 | -------------------------------------------------------------------------------- /example/simpleviewer/public/javascripts/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 | -------------------------------------------------------------------------------- /example/simpleviewer/public/javascripts/postprocessing/SavePass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.SavePass = function( renderTarget ) { 6 | 7 | var shader = THREE.ShaderExtras[ "screen" ]; 8 | 9 | this.textureID = "tDiffuse"; 10 | 11 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 12 | 13 | this.material = new THREE.ShaderMaterial( { 14 | 15 | uniforms: this.uniforms, 16 | vertexShader: shader.vertexShader, 17 | fragmentShader: shader.fragmentShader 18 | 19 | } ); 20 | 21 | this.renderTarget = renderTarget; 22 | 23 | if ( this.renderTarget === undefined ) { 24 | 25 | this.renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false }; 26 | this.renderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, this.renderTargetParameters ); 27 | 28 | } 29 | 30 | this.enabled = true; 31 | this.needsSwap = false; 32 | this.clear = false; 33 | 34 | }; 35 | 36 | THREE.SavePass.prototype = { 37 | 38 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 39 | 40 | if ( this.uniforms[ this.textureID ] ) { 41 | 42 | this.uniforms[ this.textureID ].texture = readBuffer; 43 | 44 | } 45 | 46 | THREE.EffectComposer.quad.material = this.material; 47 | 48 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, this.renderTarget, this.clear ); 49 | 50 | } 51 | 52 | }; 53 | -------------------------------------------------------------------------------- /example/simpleviewer/public/javascripts/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 ].texture = 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 | -------------------------------------------------------------------------------- /example/simpleviewer/public/javascripts/postprocessing/TexturePass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.TexturePass = function( texture, opacity ) { 6 | 7 | var shader = THREE.ShaderExtras[ "screen" ]; 8 | 9 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 10 | 11 | this.uniforms[ "opacity" ].value = ( opacity !== undefined ) ? opacity : 1.0; 12 | this.uniforms[ "tDiffuse" ].texture = texture; 13 | 14 | this.material = new THREE.ShaderMaterial( { 15 | 16 | uniforms: this.uniforms, 17 | vertexShader: shader.vertexShader, 18 | fragmentShader: shader.fragmentShader 19 | 20 | } ); 21 | 22 | this.enabled = true; 23 | this.needsSwap = false; 24 | 25 | }; 26 | 27 | THREE.TexturePass.prototype = { 28 | 29 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 30 | 31 | THREE.EffectComposer.quad.material = this.material; 32 | 33 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, readBuffer ); 34 | 35 | } 36 | 37 | }; 38 | -------------------------------------------------------------------------------- /example/simpleviewer/public/javascripts/socket.io.js: -------------------------------------------------------------------------------- 1 | /* Socket.IO.min 0.6.2 @author Guillermo Rauch , @license The MIT license., @copyright Copyright (c) 2010 LearnBoost */ 2 | var io=this.io={version:"0.6.2",setPath:function(a){window.console&&console.error&&console.error("io.setPath will be removed. Please set the variable WEB_SOCKET_SWF_LOCATION pointing to WebSocketMain.swf"),this.path=/\/$/.test(a)?a:a+"/",WEB_SOCKET_SWF_LOCATION=a+"lib/vendor/web-socket-js/WebSocketMain.swf"}};"jQuery"in this&&(jQuery.io=this.io),typeof window!="undefined"&&typeof WEB_SOCKET_SWF_LOCATION=="undefined"&&(WEB_SOCKET_SWF_LOCATION="/socket.io/lib/vendor/web-socket-js/WebSocketMain.swf"),function(){var a=this.io,b=!1;a.util={ios:!1,load:function(a){if(/loaded|complete/.test(document.readyState)||b)return a();"attachEvent"in window?window.attachEvent("onload",a):window.addEventListener("load",a,!1)},inherit:function(a,b){for(var c in b.prototype)a.prototype[c]=b.prototype[c]},indexOf:function(a,b,c){for(var d=a.length,e=c<0?Math.max(0,d+c):c||0;e"),this._doc.parentWindow.s=this,this._doc.close();var a=this._doc.createElement("div");this._doc.body.appendChild(a),this._iframe=this._doc.createElement("iframe"),a.appendChild(this._iframe),this._iframe.src=this._prepareUrl()+"/"+ +(new Date)},b.prototype._=function(a,b){this._onData(a);var c=b.getElementsByTagName("script")[0];c.parentNode.removeChild(c)},b.prototype._destroy=function(){this._iframe&&(this._iframe.src="about:blank",this._doc=null,CollectGarbage())},b.prototype.disconnect=function(){this._destroy();return a.Transport.XHR.prototype.disconnect.call(this)},b.check=function(){if("ActiveXObject"in window)try{var b=new ActiveXObject("htmlfile");return b&&a.Transport.XHR.check()}catch(c){}return!1},b.xdomainCheck=function(){return!1}}(),function(){var a=this.io,b=a.Transport["xhr-multipart"]=function(){a.Transport.XHR.apply(this,arguments)};a.util.inherit(b,a.Transport.XHR),b.prototype.type="xhr-multipart",b.prototype._get=function(){var a=this;this._xhr=this._request("","GET",!0),this._xhr.onreadystatechange=function(){a._xhr.readyState==4&&a._onData(a._xhr.responseText)},this._xhr.send(null)},b.check=function(){return"XMLHttpRequest"in window&&"prototype"in XMLHttpRequest&&"multipart"in XMLHttpRequest.prototype},b.xdomainCheck=function(){return!0}}(),function(){var a=this.io,b=new Function,c=a.Transport["xhr-polling"]=function(){a.Transport.XHR.apply(this,arguments)};a.util.inherit(c,a.Transport.XHR),c.prototype.type="xhr-polling",c.prototype.connect=function(){if(a.util.ios||a.util.android){var b=this;a.util.load(function(){setTimeout(function(){a.Transport.XHR.prototype.connect.call(b)},10)})}else a.Transport.XHR.prototype.connect.call(this)},c.prototype._get=function(){var a=this;this._xhr=this._request(+(new Date),"GET"),this._xhr.onreadystatechange=function(){var c;if(a._xhr.readyState==4){a._xhr.onreadystatechange=b;try{c=a._xhr.status}catch(d){}c==200?(a._onData(a._xhr.responseText),a._get()):a._onDisconnect()}},this._xhr.send(null)},c.check=function(){return a.Transport.XHR.check()},c.xdomainCheck=function(){return a.Transport.XHR.xdomainCheck()}}(),function(){var a=this.io;a.JSONP=[],JSONPPolling=a.Transport["jsonp-polling"]=function(){a.Transport.XHR.apply(this,arguments),this._insertAt=document.getElementsByTagName("script")[0],this._index=a.JSONP.length,a.JSONP.push(this)},a.util.inherit(JSONPPolling,a.Transport["xhr-polling"]),JSONPPolling.prototype.type="jsonp-polling",JSONPPolling.prototype._send=function(a){function h(){b._iframe&&b._form.removeChild(b._iframe);try{f=document.createElement('