├── LICENSE.md ├── README.md ├── assets ├── .DS_Store ├── head.json ├── screen.gif └── screen2.gif ├── demo1_head.html └── js ├── .DS_Store ├── GameboyShader.js ├── PixelateShader.js ├── SceneParser.js └── libs ├── .DS_Store ├── Detector.js ├── OrbitControls.js ├── postprocessing ├── BloomPass.js ├── BokehPass.js ├── DotScreenPass.js ├── EffectComposer.js ├── FilmPass.js ├── GlitchPass.js ├── MaskPass.js ├── RenderPass.js ├── SavePass.js ├── ShaderPass.js └── TexturePass.js ├── shaders ├── BasicShader.js ├── BleachBypassShader.js ├── BlendShader.js ├── BokehShader.js ├── BokehShader2.js ├── BrightnessContrastShader.js ├── ColorCorrectionShader.js ├── ColorifyShader.js ├── ConvolutionShader.js ├── CopyShader.js ├── DOFMipMapShader.js ├── DigitalGlitch.js ├── DotScreenShader.js ├── EdgeShader.js ├── EdgeShader2.js ├── FXAAShader.js ├── FilmShader.js ├── FocusShader.js ├── FresnelShader.js ├── HorizontalBlurShader.js ├── HorizontalTiltShiftShader.js ├── HueSaturationShader.js ├── KaleidoShader.js ├── LuminosityShader.js ├── MirrorShader.js ├── NormalMapShader.js ├── OceanShaders.js ├── RGBShiftShader.js ├── SSAOShader.js ├── SepiaShader.js ├── TechnicolorShader.js ├── TriangleBlurShader.js ├── UnpackDepthRGBAShader.js ├── VerticalBlurShader.js ├── VerticalTiltShiftShader.js └── VignetteShader.js └── three.min.js /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) {{{year}}} {{{fullname}}} 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ThreeJS-GameboyStyleShader 2 | ========================== 3 | 4 | A Gameboy style postprocessing effect for Three.JS. 5 | Based on http://oos.moxiecode.com/js_webgl/c64_shader/ by @oosmoxiecode. 6 | 7 | How it looks on a simple scene: 8 | 9 | ![Simple scene](/assets/screen.gif) 10 | 11 | 12 | How it looks on a game level from Kid Disco (http://kiddisco.asmallgame.com): 13 | 14 | ![Simple scene](/assets/screen2.gif) 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /assets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chribbe/ThreeJS-GameboyStyleShader/78a0dbe4d960240ef0772d833cae9e7b2ad29d61/assets/.DS_Store -------------------------------------------------------------------------------- /assets/screen.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chribbe/ThreeJS-GameboyStyleShader/78a0dbe4d960240ef0772d833cae9e7b2ad29d61/assets/screen.gif -------------------------------------------------------------------------------- /assets/screen2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chribbe/ThreeJS-GameboyStyleShader/78a0dbe4d960240ef0772d833cae9e7b2ad29d61/assets/screen2.gif -------------------------------------------------------------------------------- /demo1_head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | three.js webgl - postprocessing 5 | 6 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /js/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chribbe/ThreeJS-GameboyStyleShader/78a0dbe4d960240ef0772d833cae9e7b2ad29d61/js/.DS_Store -------------------------------------------------------------------------------- /js/GameboyShader.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @author @chribbe1 based on @oosmoxiecode original C64 Shader 4 | */ 5 | 6 | THREE.GameBoyShader = { 7 | 8 | uniforms: { 9 | 10 | "tDiffuse": { type: "t", value: null }, 11 | 12 | }, 13 | 14 | vertexShader: [ 15 | 16 | "varying vec2 vUv;", 17 | 18 | "void main() {", 19 | 20 | "vUv = uv;", 21 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 22 | 23 | "}" 24 | 25 | ].join("\n"), 26 | 27 | fragmentShader: [ 28 | 29 | "uniform sampler2D tDiffuse;", 30 | 31 | "varying vec2 vUv;", 32 | 33 | "void main() {", 34 | 35 | "vec3 c64col[4];", 36 | "c64col[0] = vec3(15.0,56.0,15.0);", 37 | "c64col[1] = vec3(48.0,98.0,48.0);", 38 | "c64col[2] = vec3(139.0,172.0,15.0);", 39 | "c64col[3] = vec3(155.0,188.0,15.0);", 40 | 41 | 42 | "vec3 samp = texture2D(tDiffuse, vUv.xy).rgb;", 43 | "vec3 match = vec3(0.0,0.0,0.0);", 44 | "float best_dot = 8.0;", 45 | 46 | "for (int c=4;c>=0;c--) {", 47 | "float this_dot = distance(c64col[c]/255.0,samp);", 48 | "if (this_dotWebGL.
', 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 | }; -------------------------------------------------------------------------------- /js/libs/OrbitControls.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author qiao / https://github.com/qiao 3 | * @author mrdoob / http://mrdoob.com 4 | * @author alteredq / http://alteredqualia.com/ 5 | * @author WestLangley / http://github.com/WestLangley 6 | * @author erich666 / http://erichaines.com 7 | */ 8 | /*global THREE, console */ 9 | 10 | // This set of controls performs orbiting, dollying (zooming), and panning. It maintains 11 | // the "up" direction as +Y, unlike the TrackballControls. Touch on tablet and phones is 12 | // supported. 13 | // 14 | // Orbit - left mouse / touch: one finger move 15 | // Zoom - middle mouse, or mousewheel / touch: two finger spread or squish 16 | // Pan - right mouse, or arrow keys / touch: three finter swipe 17 | // 18 | // This is a drop-in replacement for (most) TrackballControls used in examples. 19 | // That is, include this js file and wherever you see: 20 | // controls = new THREE.TrackballControls( camera ); 21 | // controls.target.z = 150; 22 | // Simple substitute "OrbitControls" and the control should work as-is. 23 | 24 | THREE.OrbitControls = function ( object, domElement ) { 25 | 26 | this.object = object; 27 | this.domElement = ( domElement !== undefined ) ? domElement : document; 28 | 29 | // API 30 | 31 | // Set to false to disable this control 32 | this.enabled = true; 33 | 34 | // "target" sets the location of focus, where the control orbits around 35 | // and where it pans with respect to. 36 | this.target = new THREE.Vector3(); 37 | // center is old, deprecated; use "target" instead 38 | this.center = this.target; 39 | 40 | // This option actually enables dollying in and out; left as "zoom" for 41 | // backwards compatibility 42 | this.noZoom = false; 43 | this.zoomSpeed = 1.0; 44 | // Limits to how far you can dolly in and out 45 | this.minDistance = 0; 46 | this.maxDistance = Infinity; 47 | 48 | // Set to true to disable this control 49 | this.noRotate = false; 50 | this.rotateSpeed = 1.0; 51 | 52 | // Set to true to disable this control 53 | this.noPan = false; 54 | this.keyPanSpeed = 7.0; // pixels moved per arrow key push 55 | 56 | // Set to true to automatically rotate around the target 57 | this.autoRotate = false; 58 | this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60 59 | 60 | // How far you can orbit vertically, upper and lower limits. 61 | // Range is 0 to Math.PI radians. 62 | this.minPolarAngle = 0; // radians 63 | this.maxPolarAngle = Math.PI; // radians 64 | 65 | // Set to true to disable use of the keys 66 | this.noKeys = false; 67 | // The four arrow keys 68 | this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 }; 69 | 70 | //////////// 71 | // internals 72 | 73 | var scope = this; 74 | 75 | var EPS = 0.000001; 76 | 77 | var rotateStart = new THREE.Vector2(); 78 | var rotateEnd = new THREE.Vector2(); 79 | var rotateDelta = new THREE.Vector2(); 80 | 81 | var panStart = new THREE.Vector2(); 82 | var panEnd = new THREE.Vector2(); 83 | var panDelta = new THREE.Vector2(); 84 | 85 | var dollyStart = new THREE.Vector2(); 86 | var dollyEnd = new THREE.Vector2(); 87 | var dollyDelta = new THREE.Vector2(); 88 | 89 | var phiDelta = 0; 90 | var thetaDelta = 0; 91 | var scale = 1; 92 | var pan = new THREE.Vector3(); 93 | 94 | var lastPosition = new THREE.Vector3(); 95 | 96 | var STATE = { NONE : -1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 }; 97 | var state = STATE.NONE; 98 | 99 | // events 100 | 101 | var changeEvent = { type: 'change' }; 102 | 103 | 104 | this.rotateLeft = function ( angle ) { 105 | 106 | if ( angle === undefined ) { 107 | 108 | angle = getAutoRotationAngle(); 109 | 110 | } 111 | 112 | thetaDelta -= angle; 113 | 114 | }; 115 | 116 | this.rotateUp = function ( angle ) { 117 | 118 | if ( angle === undefined ) { 119 | 120 | angle = getAutoRotationAngle(); 121 | 122 | } 123 | 124 | phiDelta -= angle; 125 | 126 | }; 127 | 128 | // pass in distance in world space to move left 129 | this.panLeft = function ( distance ) { 130 | 131 | var panOffset = new THREE.Vector3(); 132 | var te = this.object.matrix.elements; 133 | // get X column of matrix 134 | panOffset.set( te[0], te[1], te[2] ); 135 | panOffset.multiplyScalar(-distance); 136 | 137 | pan.add( panOffset ); 138 | 139 | }; 140 | 141 | // pass in distance in world space to move up 142 | this.panUp = function ( distance ) { 143 | 144 | var panOffset = new THREE.Vector3(); 145 | var te = this.object.matrix.elements; 146 | // get Y column of matrix 147 | panOffset.set( te[4], te[5], te[6] ); 148 | panOffset.multiplyScalar(distance); 149 | 150 | pan.add( panOffset ); 151 | }; 152 | 153 | // main entry point; pass in Vector2 of change desired in pixel space, 154 | // right and down are positive 155 | this.pan = function ( delta ) { 156 | 157 | var element = scope.domElement === document ? scope.domElement.body : scope.domElement; 158 | 159 | if ( scope.object.fov !== undefined ) { 160 | 161 | // perspective 162 | var position = scope.object.position; 163 | var offset = position.clone().sub( scope.target ); 164 | var targetDistance = offset.length(); 165 | 166 | // half of the fov is center to top of screen 167 | targetDistance *= Math.tan( (scope.object.fov/2) * Math.PI / 180.0 ); 168 | // we actually don't use screenWidth, since perspective camera is fixed to screen height 169 | scope.panLeft( 2 * delta.x * targetDistance / element.clientHeight ); 170 | scope.panUp( 2 * delta.y * targetDistance / element.clientHeight ); 171 | 172 | } else if ( scope.object.top !== undefined ) { 173 | 174 | // orthographic 175 | scope.panLeft( delta.x * (scope.object.right - scope.object.left) / element.clientWidth ); 176 | scope.panUp( delta.y * (scope.object.top - scope.object.bottom) / element.clientHeight ); 177 | 178 | } else { 179 | 180 | // camera neither orthographic or perspective - warn user 181 | console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' ); 182 | 183 | } 184 | 185 | }; 186 | 187 | this.dollyIn = function ( dollyScale ) { 188 | 189 | if ( dollyScale === undefined ) { 190 | 191 | dollyScale = getZoomScale(); 192 | 193 | } 194 | 195 | scale /= dollyScale; 196 | 197 | }; 198 | 199 | this.dollyOut = function ( dollyScale ) { 200 | 201 | if ( dollyScale === undefined ) { 202 | 203 | dollyScale = getZoomScale(); 204 | 205 | } 206 | 207 | scale *= dollyScale; 208 | 209 | }; 210 | 211 | this.update = function () { 212 | 213 | var position = this.object.position; 214 | var offset = position.clone().sub( this.target ); 215 | 216 | // angle from z-axis around y-axis 217 | 218 | var theta = Math.atan2( offset.x, offset.z ); 219 | 220 | // angle from y-axis 221 | 222 | var phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y ); 223 | 224 | if ( this.autoRotate ) { 225 | 226 | this.rotateLeft( getAutoRotationAngle() ); 227 | 228 | } 229 | 230 | theta += thetaDelta; 231 | phi += phiDelta; 232 | 233 | // restrict phi to be between desired limits 234 | phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) ); 235 | 236 | // restrict phi to be betwee EPS and PI-EPS 237 | phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) ); 238 | 239 | var radius = offset.length() * scale; 240 | 241 | // restrict radius to be between desired limits 242 | radius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) ); 243 | 244 | // move target to panned location 245 | this.target.add( pan ); 246 | 247 | offset.x = radius * Math.sin( phi ) * Math.sin( theta ); 248 | offset.y = radius * Math.cos( phi ); 249 | offset.z = radius * Math.sin( phi ) * Math.cos( theta ); 250 | 251 | position.copy( this.target ).add( offset ); 252 | 253 | this.object.lookAt( this.target ); 254 | 255 | thetaDelta = 0; 256 | phiDelta = 0; 257 | scale = 1; 258 | pan.set(0,0,0); 259 | 260 | if ( lastPosition.distanceTo( this.object.position ) > 0 ) { 261 | 262 | this.dispatchEvent( changeEvent ); 263 | 264 | lastPosition.copy( this.object.position ); 265 | 266 | } 267 | 268 | }; 269 | 270 | 271 | function getAutoRotationAngle() { 272 | 273 | return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed; 274 | 275 | } 276 | 277 | function getZoomScale() { 278 | 279 | return Math.pow( 0.95, scope.zoomSpeed ); 280 | 281 | } 282 | 283 | function onMouseDown( event ) { 284 | 285 | if ( scope.enabled === false ) { return; } 286 | event.preventDefault(); 287 | 288 | if ( event.button === 0 ) { 289 | if ( scope.noRotate === true ) { return; } 290 | 291 | state = STATE.ROTATE; 292 | 293 | rotateStart.set( event.clientX, event.clientY ); 294 | 295 | } else if ( event.button === 1 ) { 296 | if ( scope.noZoom === true ) { return; } 297 | 298 | state = STATE.DOLLY; 299 | 300 | dollyStart.set( event.clientX, event.clientY ); 301 | 302 | } else if ( event.button === 2 ) { 303 | if ( scope.noPan === true ) { return; } 304 | 305 | state = STATE.PAN; 306 | 307 | panStart.set( event.clientX, event.clientY ); 308 | 309 | } 310 | 311 | // Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be 312 | scope.domElement.addEventListener( 'mousemove', onMouseMove, false ); 313 | scope.domElement.addEventListener( 'mouseup', onMouseUp, false ); 314 | 315 | } 316 | 317 | function onMouseMove( event ) { 318 | 319 | if ( scope.enabled === false ) return; 320 | 321 | event.preventDefault(); 322 | 323 | var element = scope.domElement === document ? scope.domElement.body : scope.domElement; 324 | 325 | if ( state === STATE.ROTATE ) { 326 | 327 | if ( scope.noRotate === true ) return; 328 | 329 | rotateEnd.set( event.clientX, event.clientY ); 330 | rotateDelta.subVectors( rotateEnd, rotateStart ); 331 | 332 | // rotating across whole screen goes 360 degrees around 333 | scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed ); 334 | // rotating up and down along whole screen attempts to go 360, but limited to 180 335 | scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed ); 336 | 337 | rotateStart.copy( rotateEnd ); 338 | 339 | } else if ( state === STATE.DOLLY ) { 340 | 341 | if ( scope.noZoom === true ) return; 342 | 343 | dollyEnd.set( event.clientX, event.clientY ); 344 | dollyDelta.subVectors( dollyEnd, dollyStart ); 345 | 346 | if ( dollyDelta.y > 0 ) { 347 | 348 | scope.dollyIn(); 349 | 350 | } else { 351 | 352 | scope.dollyOut(); 353 | 354 | } 355 | 356 | dollyStart.copy( dollyEnd ); 357 | 358 | } else if ( state === STATE.PAN ) { 359 | 360 | if ( scope.noPan === true ) return; 361 | 362 | panEnd.set( event.clientX, event.clientY ); 363 | panDelta.subVectors( panEnd, panStart ); 364 | 365 | scope.pan( panDelta ); 366 | 367 | panStart.copy( panEnd ); 368 | 369 | } 370 | 371 | // Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be 372 | scope.update(); 373 | 374 | } 375 | 376 | function onMouseUp( /* event */ ) { 377 | 378 | if ( scope.enabled === false ) return; 379 | 380 | // Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be 381 | scope.domElement.removeEventListener( 'mousemove', onMouseMove, false ); 382 | scope.domElement.removeEventListener( 'mouseup', onMouseUp, false ); 383 | 384 | state = STATE.NONE; 385 | 386 | } 387 | 388 | function onMouseWheel( event ) { 389 | 390 | if ( scope.enabled === false || scope.noZoom === true ) return; 391 | 392 | var delta = 0; 393 | 394 | if ( event.wheelDelta ) { // WebKit / Opera / Explorer 9 395 | 396 | delta = event.wheelDelta; 397 | 398 | } else if ( event.detail ) { // Firefox 399 | 400 | delta = - event.detail; 401 | 402 | } 403 | 404 | if ( delta > 0 ) { 405 | 406 | scope.dollyOut(); 407 | 408 | } else { 409 | 410 | scope.dollyIn(); 411 | 412 | } 413 | 414 | } 415 | 416 | function onKeyDown( event ) { 417 | 418 | if ( scope.enabled === false ) { return; } 419 | if ( scope.noKeys === true ) { return; } 420 | if ( scope.noPan === true ) { return; } 421 | 422 | // pan a pixel - I guess for precise positioning? 423 | // Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be 424 | var needUpdate = false; 425 | 426 | switch ( event.keyCode ) { 427 | 428 | case scope.keys.UP: 429 | scope.pan( new THREE.Vector2( 0, scope.keyPanSpeed ) ); 430 | needUpdate = true; 431 | break; 432 | case scope.keys.BOTTOM: 433 | scope.pan( new THREE.Vector2( 0, -scope.keyPanSpeed ) ); 434 | needUpdate = true; 435 | break; 436 | case scope.keys.LEFT: 437 | scope.pan( new THREE.Vector2( scope.keyPanSpeed, 0 ) ); 438 | needUpdate = true; 439 | break; 440 | case scope.keys.RIGHT: 441 | scope.pan( new THREE.Vector2( -scope.keyPanSpeed, 0 ) ); 442 | needUpdate = true; 443 | break; 444 | } 445 | 446 | // Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be 447 | if ( needUpdate ) { 448 | 449 | scope.update(); 450 | 451 | } 452 | 453 | } 454 | 455 | function touchstart( event ) { 456 | 457 | if ( scope.enabled === false ) { return; } 458 | 459 | switch ( event.touches.length ) { 460 | 461 | case 1: // one-fingered touch: rotate 462 | if ( scope.noRotate === true ) { return; } 463 | 464 | state = STATE.TOUCH_ROTATE; 465 | 466 | rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); 467 | break; 468 | 469 | case 2: // two-fingered touch: dolly 470 | if ( scope.noZoom === true ) { return; } 471 | 472 | state = STATE.TOUCH_DOLLY; 473 | 474 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; 475 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; 476 | var distance = Math.sqrt( dx * dx + dy * dy ); 477 | dollyStart.set( 0, distance ); 478 | break; 479 | 480 | case 3: // three-fingered touch: pan 481 | if ( scope.noPan === true ) { return; } 482 | 483 | state = STATE.TOUCH_PAN; 484 | 485 | panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); 486 | break; 487 | 488 | default: 489 | state = STATE.NONE; 490 | 491 | } 492 | } 493 | 494 | function touchmove( event ) { 495 | 496 | if ( scope.enabled === false ) { return; } 497 | 498 | event.preventDefault(); 499 | event.stopPropagation(); 500 | 501 | var element = scope.domElement === document ? scope.domElement.body : scope.domElement; 502 | 503 | switch ( event.touches.length ) { 504 | 505 | case 1: // one-fingered touch: rotate 506 | if ( scope.noRotate === true ) { return; } 507 | if ( state !== STATE.TOUCH_ROTATE ) { return; } 508 | 509 | rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); 510 | rotateDelta.subVectors( rotateEnd, rotateStart ); 511 | 512 | // rotating across whole screen goes 360 degrees around 513 | scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed ); 514 | // rotating up and down along whole screen attempts to go 360, but limited to 180 515 | scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed ); 516 | 517 | rotateStart.copy( rotateEnd ); 518 | break; 519 | 520 | case 2: // two-fingered touch: dolly 521 | if ( scope.noZoom === true ) { return; } 522 | if ( state !== STATE.TOUCH_DOLLY ) { return; } 523 | 524 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; 525 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; 526 | var distance = Math.sqrt( dx * dx + dy * dy ); 527 | 528 | dollyEnd.set( 0, distance ); 529 | dollyDelta.subVectors( dollyEnd, dollyStart ); 530 | 531 | if ( dollyDelta.y > 0 ) { 532 | 533 | scope.dollyOut(); 534 | 535 | } else { 536 | 537 | scope.dollyIn(); 538 | 539 | } 540 | 541 | dollyStart.copy( dollyEnd ); 542 | break; 543 | 544 | case 3: // three-fingered touch: pan 545 | if ( scope.noPan === true ) { return; } 546 | if ( state !== STATE.TOUCH_PAN ) { return; } 547 | 548 | panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); 549 | panDelta.subVectors( panEnd, panStart ); 550 | 551 | scope.pan( panDelta ); 552 | 553 | panStart.copy( panEnd ); 554 | break; 555 | 556 | default: 557 | state = STATE.NONE; 558 | 559 | } 560 | 561 | } 562 | 563 | function touchend( /* event */ ) { 564 | 565 | if ( scope.enabled === false ) { return; } 566 | 567 | state = STATE.NONE; 568 | } 569 | 570 | this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false ); 571 | this.domElement.addEventListener( 'mousedown', onMouseDown, false ); 572 | this.domElement.addEventListener( 'mousewheel', onMouseWheel, false ); 573 | this.domElement.addEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox 574 | 575 | this.domElement.addEventListener( 'keydown', onKeyDown, false ); 576 | 577 | this.domElement.addEventListener( 'touchstart', touchstart, false ); 578 | this.domElement.addEventListener( 'touchend', touchend, false ); 579 | this.domElement.addEventListener( 'touchmove', touchmove, false ); 580 | 581 | }; 582 | 583 | THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype ); 584 | -------------------------------------------------------------------------------- /js/libs/postprocessing/BloomPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.BloomPass = function ( strength, kernelSize, sigma, resolution ) { 6 | 7 | strength = ( strength !== undefined ) ? strength : 1; 8 | kernelSize = ( kernelSize !== undefined ) ? kernelSize : 25; 9 | sigma = ( sigma !== undefined ) ? sigma : 4.0; 10 | resolution = ( resolution !== undefined ) ? resolution : 256; 11 | 12 | // render targets 13 | 14 | var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat }; 15 | 16 | this.renderTargetX = new THREE.WebGLRenderTarget( resolution, resolution, pars ); 17 | this.renderTargetY = new THREE.WebGLRenderTarget( resolution, resolution, pars ); 18 | 19 | // copy material 20 | 21 | if ( THREE.CopyShader === undefined ) 22 | console.error( "THREE.BloomPass relies on THREE.CopyShader" ); 23 | 24 | var copyShader = THREE.CopyShader; 25 | 26 | this.copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms ); 27 | 28 | this.copyUniforms[ "opacity" ].value = strength; 29 | 30 | this.materialCopy = new THREE.ShaderMaterial( { 31 | 32 | uniforms: this.copyUniforms, 33 | vertexShader: copyShader.vertexShader, 34 | fragmentShader: copyShader.fragmentShader, 35 | blending: THREE.AdditiveBlending, 36 | transparent: true 37 | 38 | } ); 39 | 40 | // convolution material 41 | 42 | if ( THREE.ConvolutionShader === undefined ) 43 | console.error( "THREE.BloomPass relies on THREE.ConvolutionShader" ); 44 | 45 | var convolutionShader = THREE.ConvolutionShader; 46 | 47 | this.convolutionUniforms = THREE.UniformsUtils.clone( convolutionShader.uniforms ); 48 | 49 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurx; 50 | this.convolutionUniforms[ "cKernel" ].value = THREE.ConvolutionShader.buildKernel( sigma ); 51 | 52 | this.materialConvolution = new THREE.ShaderMaterial( { 53 | 54 | uniforms: this.convolutionUniforms, 55 | vertexShader: convolutionShader.vertexShader, 56 | fragmentShader: convolutionShader.fragmentShader, 57 | defines: { 58 | "KERNEL_SIZE_FLOAT": kernelSize.toFixed( 1 ), 59 | "KERNEL_SIZE_INT": kernelSize.toFixed( 0 ) 60 | } 61 | 62 | } ); 63 | 64 | this.enabled = true; 65 | this.needsSwap = false; 66 | this.clear = false; 67 | 68 | 69 | this.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 ); 70 | this.scene = new THREE.Scene(); 71 | 72 | this.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null ); 73 | this.scene.add( this.quad ); 74 | 75 | }; 76 | 77 | THREE.BloomPass.prototype = { 78 | 79 | render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { 80 | 81 | if ( maskActive ) renderer.context.disable( renderer.context.STENCIL_TEST ); 82 | 83 | // Render quad with blured scene into texture (convolution pass 1) 84 | 85 | this.quad.material = this.materialConvolution; 86 | 87 | this.convolutionUniforms[ "tDiffuse" ].value = readBuffer; 88 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurX; 89 | 90 | renderer.render( this.scene, this.camera, this.renderTargetX, true ); 91 | 92 | 93 | // Render quad with blured scene into texture (convolution pass 2) 94 | 95 | this.convolutionUniforms[ "tDiffuse" ].value = this.renderTargetX; 96 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurY; 97 | 98 | renderer.render( this.scene, this.camera, this.renderTargetY, true ); 99 | 100 | // Render original scene with superimposed blur to texture 101 | 102 | this.quad.material = this.materialCopy; 103 | 104 | this.copyUniforms[ "tDiffuse" ].value = this.renderTargetY; 105 | 106 | if ( maskActive ) renderer.context.enable( renderer.context.STENCIL_TEST ); 107 | 108 | renderer.render( this.scene, this.camera, readBuffer, this.clear ); 109 | 110 | } 111 | 112 | }; 113 | 114 | THREE.BloomPass.blurX = new THREE.Vector2( 0.001953125, 0.0 ); 115 | THREE.BloomPass.blurY = new THREE.Vector2( 0.0, 0.001953125 ); 116 | -------------------------------------------------------------------------------- /js/libs/postprocessing/BokehPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Depth-of-field post-process with bokeh shader 3 | */ 4 | 5 | 6 | THREE.BokehPass = function ( scene, camera, params ) { 7 | 8 | this.scene = scene; 9 | this.camera = camera; 10 | 11 | var focus = ( params.focus !== undefined ) ? params.focus : 1.0; 12 | var aspect = ( params.aspect !== undefined ) ? params.aspect : camera.aspect; 13 | var aperture = ( params.aperture !== undefined ) ? params.aperture : 0.025; 14 | var maxblur = ( params.maxblur !== undefined ) ? params.maxblur : 1.0; 15 | 16 | // render targets 17 | 18 | var width = params.width || window.innerWidth || 1; 19 | var height = params.height || window.innerHeight || 1; 20 | 21 | this.renderTargetColor = new THREE.WebGLRenderTarget( width, height, { 22 | minFilter: THREE.LinearFilter, 23 | magFilter: THREE.LinearFilter, 24 | format: THREE.RGBFormat 25 | } ); 26 | 27 | this.renderTargetDepth = this.renderTargetColor.clone(); 28 | 29 | // depth material 30 | 31 | this.materialDepth = new THREE.MeshDepthMaterial(); 32 | 33 | // bokeh material 34 | 35 | if ( THREE.BokehShader === undefined ) { 36 | console.error( "THREE.BokehPass relies on THREE.BokehShader" ); 37 | } 38 | 39 | var bokehShader = THREE.BokehShader; 40 | var bokehUniforms = THREE.UniformsUtils.clone( bokehShader.uniforms ); 41 | 42 | bokehUniforms[ "tDepth" ].value = this.renderTargetDepth; 43 | 44 | bokehUniforms[ "focus" ].value = focus; 45 | bokehUniforms[ "aspect" ].value = aspect; 46 | bokehUniforms[ "aperture" ].value = aperture; 47 | bokehUniforms[ "maxblur" ].value = maxblur; 48 | 49 | this.materialBokeh = new THREE.ShaderMaterial({ 50 | uniforms: bokehUniforms, 51 | vertexShader: bokehShader.vertexShader, 52 | fragmentShader: bokehShader.fragmentShader 53 | }); 54 | 55 | this.uniforms = bokehUniforms; 56 | this.enabled = true; 57 | this.needsSwap = false; 58 | this.renderToScreen = false; 59 | this.clear = false; 60 | 61 | this.camera2 = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 ); 62 | this.scene2 = new THREE.Scene(); 63 | 64 | this.quad2 = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null ); 65 | this.scene2.add( this.quad2 ); 66 | 67 | }; 68 | 69 | THREE.BokehPass.prototype = { 70 | 71 | render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { 72 | 73 | this.quad2.material = this.materialBokeh; 74 | 75 | // Render depth into texture 76 | 77 | this.scene.overrideMaterial = this.materialDepth; 78 | 79 | renderer.render( this.scene, this.camera, this.renderTargetDepth, true ); 80 | 81 | // Render bokeh composite 82 | 83 | this.uniforms[ "tColor" ].value = readBuffer; 84 | 85 | if ( this.renderToScreen ) { 86 | 87 | renderer.render( this.scene2, this.camera2 ); 88 | 89 | } else { 90 | 91 | renderer.render( this.scene2, this.camera2, writeBuffer, this.clear ); 92 | 93 | } 94 | 95 | this.scene.overrideMaterial = null; 96 | 97 | } 98 | 99 | }; 100 | 101 | -------------------------------------------------------------------------------- /js/libs/postprocessing/DotScreenPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.DotScreenPass = function ( center, angle, scale ) { 6 | 7 | if ( THREE.DotScreenShader === undefined ) 8 | console.error( "THREE.DotScreenPass relies on THREE.DotScreenShader" ); 9 | 10 | var shader = THREE.DotScreenShader; 11 | 12 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 13 | 14 | if ( center !== undefined ) this.uniforms[ "center" ].value.copy( center ); 15 | if ( angle !== undefined ) this.uniforms[ "angle"].value = angle; 16 | if ( scale !== undefined ) this.uniforms[ "scale"].value = scale; 17 | 18 | this.material = new THREE.ShaderMaterial( { 19 | 20 | uniforms: this.uniforms, 21 | vertexShader: shader.vertexShader, 22 | fragmentShader: shader.fragmentShader 23 | 24 | } ); 25 | 26 | this.enabled = true; 27 | this.renderToScreen = false; 28 | this.needsSwap = true; 29 | 30 | 31 | this.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 ); 32 | this.scene = new THREE.Scene(); 33 | 34 | this.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null ); 35 | this.scene.add( this.quad ); 36 | 37 | }; 38 | 39 | THREE.DotScreenPass.prototype = { 40 | 41 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 42 | 43 | this.uniforms[ "tDiffuse" ].value = readBuffer; 44 | this.uniforms[ "tSize" ].value.set( readBuffer.width, readBuffer.height ); 45 | 46 | this.quad.material = this.material; 47 | 48 | if ( this.renderToScreen ) { 49 | 50 | renderer.render( this.scene, this.camera ); 51 | 52 | } else { 53 | 54 | renderer.render( this.scene, this.camera, writeBuffer, false ); 55 | 56 | } 57 | 58 | } 59 | 60 | }; 61 | -------------------------------------------------------------------------------- /js/libs/postprocessing/EffectComposer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.EffectComposer = function ( renderer, renderTarget ) { 6 | 7 | this.renderer = renderer; 8 | 9 | if ( renderTarget === undefined ) { 10 | 11 | var width = window.innerWidth || 1; 12 | var height = window.innerHeight || 1; 13 | var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false }; 14 | 15 | renderTarget = new THREE.WebGLRenderTarget( width, height, parameters ); 16 | 17 | } 18 | 19 | this.renderTarget1 = renderTarget; 20 | this.renderTarget2 = renderTarget.clone(); 21 | 22 | this.writeBuffer = this.renderTarget1; 23 | this.readBuffer = this.renderTarget2; 24 | 25 | this.passes = []; 26 | 27 | if ( THREE.CopyShader === undefined ) 28 | console.error( "THREE.EffectComposer relies on THREE.CopyShader" ); 29 | 30 | this.copyPass = new THREE.ShaderPass( THREE.CopyShader ); 31 | 32 | }; 33 | 34 | THREE.EffectComposer.prototype = { 35 | 36 | swapBuffers: function() { 37 | 38 | var tmp = this.readBuffer; 39 | this.readBuffer = this.writeBuffer; 40 | this.writeBuffer = tmp; 41 | 42 | }, 43 | 44 | addPass: function ( pass ) { 45 | 46 | this.passes.push( pass ); 47 | 48 | }, 49 | 50 | insertPass: function ( pass, index ) { 51 | 52 | this.passes.splice( index, 0, pass ); 53 | 54 | }, 55 | 56 | render: function ( delta ) { 57 | 58 | this.writeBuffer = this.renderTarget1; 59 | this.readBuffer = this.renderTarget2; 60 | 61 | var maskActive = false; 62 | 63 | var pass, i, il = this.passes.length; 64 | 65 | for ( i = 0; i < il; i ++ ) { 66 | 67 | pass = this.passes[ i ]; 68 | 69 | if ( !pass.enabled ) continue; 70 | 71 | pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive ); 72 | 73 | if ( pass.needsSwap ) { 74 | 75 | if ( maskActive ) { 76 | 77 | var context = this.renderer.context; 78 | 79 | context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff ); 80 | 81 | this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta ); 82 | 83 | context.stencilFunc( context.EQUAL, 1, 0xffffffff ); 84 | 85 | } 86 | 87 | this.swapBuffers(); 88 | 89 | } 90 | 91 | if ( pass instanceof THREE.MaskPass ) { 92 | 93 | maskActive = true; 94 | 95 | } else if ( pass instanceof THREE.ClearMaskPass ) { 96 | 97 | maskActive = false; 98 | 99 | } 100 | 101 | } 102 | 103 | }, 104 | 105 | reset: function ( renderTarget ) { 106 | 107 | if ( renderTarget === undefined ) { 108 | 109 | renderTarget = this.renderTarget1.clone(); 110 | 111 | renderTarget.width = window.innerWidth; 112 | renderTarget.height = window.innerHeight; 113 | 114 | } 115 | 116 | this.renderTarget1 = renderTarget; 117 | this.renderTarget2 = renderTarget.clone(); 118 | 119 | this.writeBuffer = this.renderTarget1; 120 | this.readBuffer = this.renderTarget2; 121 | 122 | }, 123 | 124 | setSize: function ( width, height ) { 125 | 126 | var renderTarget = this.renderTarget1.clone(); 127 | 128 | renderTarget.width = width; 129 | renderTarget.height = height; 130 | 131 | this.reset( renderTarget ); 132 | 133 | } 134 | 135 | }; 136 | -------------------------------------------------------------------------------- /js/libs/postprocessing/FilmPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.FilmPass = function ( noiseIntensity, scanlinesIntensity, scanlinesCount, grayscale ) { 6 | 7 | if ( THREE.FilmShader === undefined ) 8 | console.error( "THREE.FilmPass relies on THREE.FilmShader" ); 9 | 10 | var shader = THREE.FilmShader; 11 | 12 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 13 | 14 | this.material = new THREE.ShaderMaterial( { 15 | 16 | uniforms: this.uniforms, 17 | vertexShader: shader.vertexShader, 18 | fragmentShader: shader.fragmentShader 19 | 20 | } ); 21 | 22 | if ( grayscale !== undefined ) this.uniforms.grayscale.value = grayscale; 23 | if ( noiseIntensity !== undefined ) this.uniforms.nIntensity.value = noiseIntensity; 24 | if ( scanlinesIntensity !== undefined ) this.uniforms.sIntensity.value = scanlinesIntensity; 25 | if ( scanlinesCount !== undefined ) this.uniforms.sCount.value = scanlinesCount; 26 | 27 | this.enabled = true; 28 | this.renderToScreen = false; 29 | this.needsSwap = true; 30 | 31 | 32 | this.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 ); 33 | this.scene = new THREE.Scene(); 34 | 35 | this.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null ); 36 | this.scene.add( this.quad ); 37 | 38 | }; 39 | 40 | THREE.FilmPass.prototype = { 41 | 42 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 43 | 44 | this.uniforms[ "tDiffuse" ].value = readBuffer; 45 | this.uniforms[ "time" ].value += delta; 46 | 47 | this.quad.material = this.material; 48 | 49 | if ( this.renderToScreen ) { 50 | 51 | renderer.render( this.scene, this.camera ); 52 | 53 | } else { 54 | 55 | renderer.render( this.scene, this.camera, writeBuffer, false ); 56 | 57 | } 58 | 59 | } 60 | 61 | }; 62 | -------------------------------------------------------------------------------- /js/libs/postprocessing/GlitchPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | */ 4 | 5 | THREE.GlitchPass = function ( dt_size ) { 6 | 7 | if ( THREE.DigitalGlitch === undefined ) console.error( "THREE.GlitchPass relies on THREE.DigitalGlitch" ); 8 | 9 | var shader = THREE.DigitalGlitch; 10 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 11 | 12 | if(dt_size==undefined) dt_size=64; 13 | 14 | 15 | this.uniforms[ "tDisp"].value=this.generateHeightmap(dt_size); 16 | 17 | 18 | this.material = new THREE.ShaderMaterial({ 19 | uniforms: this.uniforms, 20 | vertexShader: shader.vertexShader, 21 | fragmentShader: shader.fragmentShader 22 | }); 23 | 24 | console.log(this.material); 25 | 26 | this.enabled = true; 27 | this.renderToScreen = false; 28 | this.needsSwap = true; 29 | 30 | 31 | this.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 ); 32 | this.scene = new THREE.Scene(); 33 | 34 | this.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null ); 35 | this.scene.add( this.quad ); 36 | 37 | this.goWild=false; 38 | this.curF=0; 39 | this.generateTrigger(); 40 | 41 | }; 42 | 43 | THREE.GlitchPass.prototype = { 44 | 45 | render: function ( renderer, writeBuffer, readBuffer, delta ) 46 | { 47 | this.uniforms[ "tDiffuse" ].value = readBuffer; 48 | this.uniforms[ 'seed' ].value=Math.random();//default seeding 49 | this.uniforms[ 'byp' ].value=0; 50 | 51 | if(this.curF % this.randX ==0 || this.goWild==true) 52 | { 53 | this.uniforms[ 'amount' ].value=Math.random()/30; 54 | this.uniforms[ 'angle' ].value=THREE.Math.randFloat(-Math.PI,Math.PI); 55 | this.uniforms[ 'seed_x' ].value=THREE.Math.randFloat(-1,1); 56 | this.uniforms[ 'seed_y' ].value=THREE.Math.randFloat(-1,1); 57 | this.uniforms[ 'distortion_x' ].value=THREE.Math.randFloat(0,1); 58 | this.uniforms[ 'distortion_y' ].value=THREE.Math.randFloat(0,1); 59 | this.curF=0; 60 | this.generateTrigger(); 61 | } 62 | else if(this.curF % this.randX 0.0) ? b : c;", 315 | "} else {", 316 | "float f = focalLength; // focal length in mm", 317 | "float d = fDepth*1000.0; // focal plane in mm", 318 | "float o = depth*1000.0; // depth in mm", 319 | 320 | "float a = (o*f)/(o-f);", 321 | "float b = (d*f)/(d-f);", 322 | "float c = (d-f)/(d*fstop*CoC);", 323 | 324 | "blur = abs(a-b)*c;", 325 | "}", 326 | 327 | "blur = clamp(blur,0.0,1.0);", 328 | 329 | "// calculation of pattern for dithering", 330 | 331 | "vec2 noise = rand(vUv.xy)*namount*blur;", 332 | 333 | "// getting blur x and y step factor", 334 | 335 | "float w = (1.0/width)*blur*maxblur+noise.x;", 336 | "float h = (1.0/height)*blur*maxblur+noise.y;", 337 | 338 | "// calculation of final color", 339 | 340 | "vec3 col = vec3(0.0);", 341 | 342 | "if(blur < 0.05) {", 343 | "//some optimization thingy", 344 | "col = texture2D(tColor, vUv.xy).rgb;", 345 | "} else {", 346 | "col = texture2D(tColor, vUv.xy).rgb;", 347 | "float s = 1.0;", 348 | "int ringsamples;", 349 | 350 | "for (int i = 1; i <= rings; i++) {", 351 | "/*unboxstart*/", 352 | "ringsamples = i * samples;", 353 | 354 | "for (int j = 0 ; j < maxringsamples ; j++) {", 355 | "if (j >= ringsamples) break;", 356 | "s += gather(float(i), float(j), ringsamples, col, w, h, blur);", 357 | "}", 358 | "/*unboxend*/", 359 | "}", 360 | 361 | "col /= s; //divide by sample count", 362 | "}", 363 | 364 | "if (showFocus) {", 365 | "col = debugFocus(col, blur, depth);", 366 | "}", 367 | 368 | "if (vignetting) {", 369 | "col *= vignette();", 370 | "}", 371 | 372 | "gl_FragColor.rgb = col;", 373 | "gl_FragColor.a = 1.0;", 374 | "} " 375 | 376 | ].join("\n") 377 | 378 | }; 379 | -------------------------------------------------------------------------------- /js/libs/shaders/BrightnessContrastShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author tapio / http://tapio.github.com/ 3 | * 4 | * Brightness and contrast adjustment 5 | * https://github.com/evanw/glfx.js 6 | * brightness: -1 to 1 (-1 is solid black, 0 is no change, and 1 is solid white) 7 | * contrast: -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast) 8 | */ 9 | 10 | THREE.BrightnessContrastShader = { 11 | 12 | uniforms: { 13 | 14 | "tDiffuse": { type: "t", value: null }, 15 | "brightness": { type: "f", value: 0 }, 16 | "contrast": { type: "f", value: 0 } 17 | 18 | }, 19 | 20 | vertexShader: [ 21 | 22 | "varying vec2 vUv;", 23 | 24 | "void main() {", 25 | 26 | "vUv = uv;", 27 | 28 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 29 | 30 | "}" 31 | 32 | ].join("\n"), 33 | 34 | fragmentShader: [ 35 | 36 | "uniform sampler2D tDiffuse;", 37 | "uniform float brightness;", 38 | "uniform float contrast;", 39 | 40 | "varying vec2 vUv;", 41 | 42 | "void main() {", 43 | 44 | "gl_FragColor = texture2D( tDiffuse, vUv );", 45 | 46 | "gl_FragColor.rgb += brightness;", 47 | 48 | "if (contrast > 0.0) {", 49 | "gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) / (1.0 - contrast) + 0.5;", 50 | "} else {", 51 | "gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) * (1.0 + contrast) + 0.5;", 52 | "}", 53 | 54 | "}" 55 | 56 | ].join("\n") 57 | 58 | }; 59 | -------------------------------------------------------------------------------- /js/libs/shaders/ColorCorrectionShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Color correction 5 | */ 6 | 7 | THREE.ColorCorrectionShader = { 8 | 9 | uniforms: { 10 | 11 | "tDiffuse": { type: "t", value: null }, 12 | "powRGB": { type: "v3", value: new THREE.Vector3( 2, 2, 2 ) }, 13 | "mulRGB": { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) } 14 | 15 | }, 16 | 17 | vertexShader: [ 18 | 19 | "varying vec2 vUv;", 20 | 21 | "void main() {", 22 | 23 | "vUv = uv;", 24 | 25 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 26 | 27 | "}" 28 | 29 | ].join("\n"), 30 | 31 | fragmentShader: [ 32 | 33 | "uniform sampler2D tDiffuse;", 34 | "uniform vec3 powRGB;", 35 | "uniform vec3 mulRGB;", 36 | 37 | "varying vec2 vUv;", 38 | 39 | "void main() {", 40 | 41 | "gl_FragColor = texture2D( tDiffuse, vUv );", 42 | "gl_FragColor.rgb = mulRGB * pow( gl_FragColor.rgb, powRGB );", 43 | 44 | "}" 45 | 46 | ].join("\n") 47 | 48 | }; 49 | -------------------------------------------------------------------------------- /js/libs/shaders/ColorifyShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Colorify shader 5 | */ 6 | 7 | THREE.ColorifyShader = { 8 | 9 | uniforms: { 10 | 11 | "tDiffuse": { type: "t", value: null }, 12 | "color": { type: "c", value: new THREE.Color( 0xffffff ) } 13 | 14 | }, 15 | 16 | vertexShader: [ 17 | 18 | "varying vec2 vUv;", 19 | 20 | "void main() {", 21 | 22 | "vUv = uv;", 23 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 24 | 25 | "}" 26 | 27 | ].join("\n"), 28 | 29 | fragmentShader: [ 30 | 31 | "uniform vec3 color;", 32 | "uniform sampler2D tDiffuse;", 33 | 34 | "varying vec2 vUv;", 35 | 36 | "void main() {", 37 | 38 | "vec4 texel = texture2D( tDiffuse, vUv );", 39 | 40 | "vec3 luma = vec3( 0.299, 0.587, 0.114 );", 41 | "float v = dot( texel.xyz, luma );", 42 | 43 | "gl_FragColor = vec4( v * color, texel.w );", 44 | 45 | "}" 46 | 47 | ].join("\n") 48 | 49 | }; 50 | -------------------------------------------------------------------------------- /js/libs/shaders/ConvolutionShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Convolution shader 5 | * ported from o3d sample to WebGL / GLSL 6 | * http://o3d.googlecode.com/svn/trunk/samples/convolution.html 7 | */ 8 | 9 | THREE.ConvolutionShader = { 10 | 11 | defines: { 12 | 13 | "KERNEL_SIZE_FLOAT": "25.0", 14 | "KERNEL_SIZE_INT": "25", 15 | 16 | }, 17 | 18 | uniforms: { 19 | 20 | "tDiffuse": { type: "t", value: null }, 21 | "uImageIncrement": { type: "v2", value: new THREE.Vector2( 0.001953125, 0.0 ) }, 22 | "cKernel": { type: "fv1", value: [] } 23 | 24 | }, 25 | 26 | vertexShader: [ 27 | 28 | "uniform vec2 uImageIncrement;", 29 | 30 | "varying vec2 vUv;", 31 | 32 | "void main() {", 33 | 34 | "vUv = uv - ( ( KERNEL_SIZE_FLOAT - 1.0 ) / 2.0 ) * uImageIncrement;", 35 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 36 | 37 | "}" 38 | 39 | ].join("\n"), 40 | 41 | fragmentShader: [ 42 | 43 | "uniform float cKernel[ KERNEL_SIZE_INT ];", 44 | 45 | "uniform sampler2D tDiffuse;", 46 | "uniform vec2 uImageIncrement;", 47 | 48 | "varying vec2 vUv;", 49 | 50 | "void main() {", 51 | 52 | "vec2 imageCoord = vUv;", 53 | "vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );", 54 | 55 | "for( int i = 0; i < KERNEL_SIZE_INT; i ++ ) {", 56 | 57 | "sum += texture2D( tDiffuse, imageCoord ) * cKernel[ i ];", 58 | "imageCoord += uImageIncrement;", 59 | 60 | "}", 61 | 62 | "gl_FragColor = sum;", 63 | 64 | "}" 65 | 66 | 67 | ].join("\n"), 68 | 69 | buildKernel: function ( sigma ) { 70 | 71 | // We lop off the sqrt(2 * pi) * sigma term, since we're going to normalize anyway. 72 | 73 | function gauss( x, sigma ) { 74 | 75 | return Math.exp( - ( x * x ) / ( 2.0 * sigma * sigma ) ); 76 | 77 | } 78 | 79 | var i, values, sum, halfWidth, kMaxKernelSize = 25, kernelSize = 2 * Math.ceil( sigma * 3.0 ) + 1; 80 | 81 | if ( kernelSize > kMaxKernelSize ) kernelSize = kMaxKernelSize; 82 | halfWidth = ( kernelSize - 1 ) * 0.5; 83 | 84 | values = new Array( kernelSize ); 85 | sum = 0.0; 86 | for ( i = 0; i < kernelSize; ++i ) { 87 | 88 | values[ i ] = gauss( i - halfWidth, sigma ); 89 | sum += values[ i ]; 90 | 91 | } 92 | 93 | // normalize the kernel 94 | 95 | for ( i = 0; i < kernelSize; ++i ) values[ i ] /= sum; 96 | 97 | return values; 98 | 99 | } 100 | 101 | }; 102 | -------------------------------------------------------------------------------- /js/libs/shaders/CopyShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Full-screen textured quad shader 5 | */ 6 | 7 | THREE.CopyShader = { 8 | 9 | uniforms: { 10 | 11 | "tDiffuse": { type: "t", value: null }, 12 | "opacity": { type: "f", value: 1.0 } 13 | 14 | }, 15 | 16 | vertexShader: [ 17 | 18 | "varying vec2 vUv;", 19 | 20 | "void main() {", 21 | 22 | "vUv = uv;", 23 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 24 | 25 | "}" 26 | 27 | ].join("\n"), 28 | 29 | fragmentShader: [ 30 | 31 | "uniform float opacity;", 32 | 33 | "uniform sampler2D tDiffuse;", 34 | 35 | "varying vec2 vUv;", 36 | 37 | "void main() {", 38 | 39 | "vec4 texel = texture2D( tDiffuse, vUv );", 40 | "gl_FragColor = opacity * texel;", 41 | 42 | "}" 43 | 44 | ].join("\n") 45 | 46 | }; 47 | -------------------------------------------------------------------------------- /js/libs/shaders/DOFMipMapShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Depth-of-field shader using mipmaps 5 | * - from Matt Handley @applmak 6 | * - requires power-of-2 sized render target with enabled mipmaps 7 | */ 8 | 9 | THREE.DOFMipMapShader = { 10 | 11 | uniforms: { 12 | 13 | "tColor": { type: "t", value: null }, 14 | "tDepth": { type: "t", value: null }, 15 | "focus": { type: "f", value: 1.0 }, 16 | "maxblur": { type: "f", value: 1.0 } 17 | 18 | }, 19 | 20 | vertexShader: [ 21 | 22 | "varying vec2 vUv;", 23 | 24 | "void main() {", 25 | 26 | "vUv = uv;", 27 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 28 | 29 | "}" 30 | 31 | ].join("\n"), 32 | 33 | fragmentShader: [ 34 | 35 | "uniform float focus;", 36 | "uniform float maxblur;", 37 | 38 | "uniform sampler2D tColor;", 39 | "uniform sampler2D tDepth;", 40 | 41 | "varying vec2 vUv;", 42 | 43 | "void main() {", 44 | 45 | "vec4 depth = texture2D( tDepth, vUv );", 46 | 47 | "float factor = depth.x - focus;", 48 | 49 | "vec4 col = texture2D( tColor, vUv, 2.0 * maxblur * abs( focus - depth.x ) );", 50 | 51 | "gl_FragColor = col;", 52 | "gl_FragColor.a = 1.0;", 53 | 54 | "}" 55 | 56 | ].join("\n") 57 | 58 | }; 59 | -------------------------------------------------------------------------------- /js/libs/shaders/DigitalGlitch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author felixturner / http://airtight.cc/ 3 | * 4 | * RGB Shift Shader 5 | * Shifts red and blue channels from center in opposite directions 6 | * Ported from http://kriss.cx/tom/2009/05/rgb-shift/ 7 | * by Tom Butterworth / http://kriss.cx/tom/ 8 | * 9 | * amount: shift distance (1 is width of input) 10 | * angle: shift angle in radians 11 | */ 12 | 13 | THREE.DigitalGlitch = { 14 | 15 | uniforms: { 16 | 17 | "tDiffuse": { type: "t", value: null },//diffuse texture 18 | "tDisp": { type: "t", value: null },//displacement texture for digital glitch squares 19 | "byp": { type: "i", value: 0 },//apply the glitch ? 20 | "amount": { type: "f", value: 0.08 }, 21 | "angle": { type: "f", value: 0.02 }, 22 | "seed": { type: "f", value: 0.02 }, 23 | "seed_x": { type: "f", value: 0.02 },//-1,1 24 | "seed_y": { type: "f", value: 0.02 },//-1,1 25 | "distortion_x": { type: "f", value: 0.5 }, 26 | "distortion_y": { type: "f", value: 0.6 }, 27 | "col_s": { type: "f", value: 0.05 } 28 | }, 29 | 30 | vertexShader: [ 31 | 32 | "varying vec2 vUv;", 33 | "void main() {", 34 | "vUv = uv;", 35 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 36 | "}" 37 | ].join("\n"), 38 | 39 | fragmentShader: [ 40 | "uniform int byp;",//should we apply the glitch ? 41 | 42 | "uniform sampler2D tDiffuse;", 43 | "uniform sampler2D tDisp;", 44 | 45 | "uniform float amount;", 46 | "uniform float angle;", 47 | "uniform float seed;", 48 | "uniform float seed_x;", 49 | "uniform float seed_y;", 50 | "uniform float distortion_x;", 51 | "uniform float distortion_y;", 52 | "uniform float col_s;", 53 | 54 | "varying vec2 vUv;", 55 | 56 | 57 | "float rand(vec2 co){", 58 | "return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);", 59 | "}", 60 | 61 | "void main() {", 62 | "if(byp<1) {", 63 | "vec2 p = vUv;", 64 | "float xs = floor(gl_FragCoord.x / 0.5);", 65 | "float ys = floor(gl_FragCoord.y / 0.5);", 66 | //based on staffantans glitch shader for unity https://github.com/staffantan/unityglitch 67 | "vec4 normal = texture2D (tDisp, p*seed*seed);", 68 | "if(p.ydistortion_x-col_s*seed) {", 69 | "if(seed_x>0.){", 70 | "p.y = 1. - (p.y + distortion_y);", 71 | "}", 72 | "else {", 73 | "p.y = distortion_y;", 74 | "}", 75 | "}", 76 | "if(p.xdistortion_y-col_s*seed) {", 77 | "if(seed_y>0.){", 78 | "p.x=distortion_x;", 79 | "}", 80 | "else {", 81 | "p.x = 1. - (p.x + distortion_x);", 82 | "}", 83 | "}", 84 | "p.x+=normal.x*seed_x*(seed/5.);", 85 | "p.y+=normal.y*seed_y*(seed/5.);", 86 | //base from RGB shift shader 87 | "vec2 offset = amount * vec2( cos(angle), sin(angle));", 88 | "vec4 cr = texture2D(tDiffuse, p + offset);", 89 | "vec4 cga = texture2D(tDiffuse, p);", 90 | "vec4 cb = texture2D(tDiffuse, p - offset);", 91 | "gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);", 92 | //add noise 93 | "vec4 snow = 200.*amount*vec4(rand(vec2(xs * seed,ys * seed*50.))*0.2);", 94 | "gl_FragColor = gl_FragColor+ snow;", 95 | "}", 96 | "else {", 97 | "gl_FragColor=texture2D (tDiffuse, vUv);", 98 | "}", 99 | "}" 100 | 101 | ].join("\n") 102 | 103 | }; 104 | -------------------------------------------------------------------------------- /js/libs/shaders/DotScreenShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Dot screen shader 5 | * based on glfx.js sepia shader 6 | * https://github.com/evanw/glfx.js 7 | */ 8 | 9 | THREE.DotScreenShader = { 10 | 11 | uniforms: { 12 | 13 | "tDiffuse": { type: "t", value: null }, 14 | "tSize": { type: "v2", value: new THREE.Vector2( 256, 256 ) }, 15 | "center": { type: "v2", value: new THREE.Vector2( 0.5, 0.5 ) }, 16 | "angle": { type: "f", value: 1.57 }, 17 | "scale": { type: "f", value: 1.0 } 18 | 19 | }, 20 | 21 | vertexShader: [ 22 | 23 | "varying vec2 vUv;", 24 | 25 | "void main() {", 26 | 27 | "vUv = uv;", 28 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 29 | 30 | "}" 31 | 32 | ].join("\n"), 33 | 34 | fragmentShader: [ 35 | 36 | "uniform vec2 center;", 37 | "uniform float angle;", 38 | "uniform float scale;", 39 | "uniform vec2 tSize;", 40 | 41 | "uniform sampler2D tDiffuse;", 42 | 43 | "varying vec2 vUv;", 44 | 45 | "float pattern() {", 46 | 47 | "float s = sin( angle ), c = cos( angle );", 48 | 49 | "vec2 tex = vUv * tSize - center;", 50 | "vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale;", 51 | 52 | "return ( sin( point.x ) * sin( point.y ) ) * 4.0;", 53 | 54 | "}", 55 | 56 | "void main() {", 57 | 58 | "vec4 color = texture2D( tDiffuse, vUv );", 59 | 60 | "float average = ( color.r + color.g + color.b ) / 3.0;", 61 | 62 | "gl_FragColor = vec4( vec3( average * 10.0 - 5.0 + pattern() ), color.a );", 63 | 64 | "}" 65 | 66 | ].join("\n") 67 | 68 | }; 69 | -------------------------------------------------------------------------------- /js/libs/shaders/EdgeShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author zz85 / https://github.com/zz85 | https://www.lab4games.net/zz85/blog 3 | * 4 | * Edge Detection Shader using Frei-Chen filter 5 | * Based on http://rastergrid.com/blog/2011/01/frei-chen-edge-detector 6 | * 7 | * aspect: vec2 of (1/width, 1/height) 8 | */ 9 | 10 | THREE.EdgeShader = { 11 | 12 | uniforms: { 13 | 14 | "tDiffuse": { type: "t", value: null }, 15 | "aspect": { type: "v2", value: new THREE.Vector2( 512, 512 ) }, 16 | }, 17 | 18 | vertexShader: [ 19 | 20 | "varying vec2 vUv;", 21 | 22 | "void main() {", 23 | 24 | "vUv = uv;", 25 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 26 | 27 | "}" 28 | 29 | ].join("\n"), 30 | 31 | fragmentShader: [ 32 | 33 | "uniform sampler2D tDiffuse;", 34 | "varying vec2 vUv;", 35 | 36 | "uniform vec2 aspect;", 37 | 38 | "vec2 texel = vec2(1.0 / aspect.x, 1.0 / aspect.y);", 39 | 40 | 41 | "mat3 G[9];", 42 | 43 | // hard coded matrix values!!!! as suggested in https://github.com/neilmendoza/ofxPostProcessing/blob/master/src/EdgePass.cpp#L45 44 | 45 | "const mat3 g0 = mat3( 0.3535533845424652, 0, -0.3535533845424652, 0.5, 0, -0.5, 0.3535533845424652, 0, -0.3535533845424652 );", 46 | "const mat3 g1 = mat3( 0.3535533845424652, 0.5, 0.3535533845424652, 0, 0, 0, -0.3535533845424652, -0.5, -0.3535533845424652 );", 47 | "const mat3 g2 = mat3( 0, 0.3535533845424652, -0.5, -0.3535533845424652, 0, 0.3535533845424652, 0.5, -0.3535533845424652, 0 );", 48 | "const mat3 g3 = mat3( 0.5, -0.3535533845424652, 0, -0.3535533845424652, 0, 0.3535533845424652, 0, 0.3535533845424652, -0.5 );", 49 | "const mat3 g4 = mat3( 0, -0.5, 0, 0.5, 0, 0.5, 0, -0.5, 0 );", 50 | "const mat3 g5 = mat3( -0.5, 0, 0.5, 0, 0, 0, 0.5, 0, -0.5 );", 51 | "const mat3 g6 = mat3( 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.6666666865348816, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204 );", 52 | "const mat3 g7 = mat3( -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, 0.6666666865348816, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408 );", 53 | "const mat3 g8 = mat3( 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408 );", 54 | 55 | "void main(void)", 56 | "{", 57 | 58 | "G[0] = g0,", 59 | "G[1] = g1,", 60 | "G[2] = g2,", 61 | "G[3] = g3,", 62 | "G[4] = g4,", 63 | "G[5] = g5,", 64 | "G[6] = g6,", 65 | "G[7] = g7,", 66 | "G[8] = g8;", 67 | 68 | "mat3 I;", 69 | "float cnv[9];", 70 | "vec3 sample;", 71 | 72 | /* fetch the 3x3 neighbourhood and use the RGB vector's length as intensity value */ 73 | "for (float i=0.0; i<3.0; i++) {", 74 | "for (float j=0.0; j<3.0; j++) {", 75 | "sample = texture2D(tDiffuse, vUv + texel * vec2(i-1.0,j-1.0) ).rgb;", 76 | "I[int(i)][int(j)] = length(sample);", 77 | "}", 78 | "}", 79 | 80 | /* calculate the convolution values for all the masks */ 81 | "for (int i=0; i<9; i++) {", 82 | "float dp3 = dot(G[i][0], I[0]) + dot(G[i][1], I[1]) + dot(G[i][2], I[2]);", 83 | "cnv[i] = dp3 * dp3;", 84 | "}", 85 | 86 | "float M = (cnv[0] + cnv[1]) + (cnv[2] + cnv[3]);", 87 | "float S = (cnv[4] + cnv[5]) + (cnv[6] + cnv[7]) + (cnv[8] + M);", 88 | 89 | "gl_FragColor = vec4(vec3(sqrt(M/S)), 1.0);", 90 | "}", 91 | 92 | ].join("\n") 93 | }; 94 | -------------------------------------------------------------------------------- /js/libs/shaders/EdgeShader2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author zz85 / https://github.com/zz85 | https://www.lab4games.net/zz85/blog 3 | * 4 | * Edge Detection Shader using Sobel filter 5 | * Based on http://rastergrid.com/blog/2011/01/frei-chen-edge-detector 6 | * 7 | * aspect: vec2 of (1/width, 1/height) 8 | */ 9 | 10 | THREE.EdgeShader2 = { 11 | 12 | uniforms: { 13 | 14 | "tDiffuse": { type: "t", value: null }, 15 | "aspect": { type: "v2", value: new THREE.Vector2( 512, 512 ) }, 16 | }, 17 | 18 | vertexShader: [ 19 | 20 | "varying vec2 vUv;", 21 | 22 | "void main() {", 23 | 24 | "vUv = uv;", 25 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 26 | 27 | "}" 28 | 29 | ].join("\n"), 30 | 31 | fragmentShader: [ 32 | 33 | "uniform sampler2D tDiffuse;", 34 | "varying vec2 vUv;", 35 | "uniform vec2 aspect;", 36 | 37 | 38 | "vec2 texel = vec2(1.0 / aspect.x, 1.0 / aspect.y);", 39 | 40 | "mat3 G[2];", 41 | 42 | "const mat3 g0 = mat3( 1.0, 2.0, 1.0, 0.0, 0.0, 0.0, -1.0, -2.0, -1.0 );", 43 | "const mat3 g1 = mat3( 1.0, 0.0, -1.0, 2.0, 0.0, -2.0, 1.0, 0.0, -1.0 );", 44 | 45 | 46 | "void main(void)", 47 | "{", 48 | "mat3 I;", 49 | "float cnv[2];", 50 | "vec3 sample;", 51 | 52 | "G[0] = g0;", 53 | "G[1] = g1;", 54 | 55 | /* fetch the 3x3 neighbourhood and use the RGB vector's length as intensity value */ 56 | "for (float i=0.0; i<3.0; i++)", 57 | "for (float j=0.0; j<3.0; j++) {", 58 | "sample = texture2D( tDiffuse, vUv + texel * vec2(i-1.0,j-1.0) ).rgb;", 59 | "I[int(i)][int(j)] = length(sample);", 60 | "}", 61 | 62 | /* calculate the convolution values for all the masks */ 63 | "for (int i=0; i<2; i++) {", 64 | "float dp3 = dot(G[i][0], I[0]) + dot(G[i][1], I[1]) + dot(G[i][2], I[2]);", 65 | "cnv[i] = dp3 * dp3; ", 66 | "}", 67 | 68 | "gl_FragColor = vec4(0.5 * sqrt(cnv[0]*cnv[0]+cnv[1]*cnv[1]));", 69 | "} ", 70 | 71 | ].join("\n") 72 | 73 | }; 74 | -------------------------------------------------------------------------------- /js/libs/shaders/FXAAShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * @author davidedc / http://www.sketchpatch.net/ 4 | * 5 | * NVIDIA FXAA by Timothy Lottes 6 | * http://timothylottes.blogspot.com/2011/06/fxaa3-source-released.html 7 | * - WebGL port by @supereggbert 8 | * http://www.glge.org/demos/fxaa/ 9 | */ 10 | 11 | THREE.FXAAShader = { 12 | 13 | uniforms: { 14 | 15 | "tDiffuse": { type: "t", value: null }, 16 | "resolution": { type: "v2", value: new THREE.Vector2( 1 / 1024, 1 / 512 ) } 17 | 18 | }, 19 | 20 | vertexShader: [ 21 | 22 | "varying vec2 vUv;", 23 | 24 | "void main() {", 25 | 26 | "vUv = uv;", 27 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 28 | 29 | "}" 30 | 31 | ].join("\n"), 32 | 33 | fragmentShader: [ 34 | 35 | "uniform sampler2D tDiffuse;", 36 | "uniform vec2 resolution;", 37 | 38 | "varying vec2 vUv;", 39 | 40 | "#define FXAA_REDUCE_MIN (1.0/128.0)", 41 | "#define FXAA_REDUCE_MUL (1.0/8.0)", 42 | "#define FXAA_SPAN_MAX 8.0", 43 | 44 | "void main() {", 45 | 46 | "vec3 rgbNW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ).xyz;", 47 | "vec3 rgbNE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ).xyz;", 48 | "vec3 rgbSW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ).xyz;", 49 | "vec3 rgbSE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ).xyz;", 50 | "vec4 rgbaM = texture2D( tDiffuse, gl_FragCoord.xy * resolution );", 51 | "vec3 rgbM = rgbaM.xyz;", 52 | "vec3 luma = vec3( 0.299, 0.587, 0.114 );", 53 | 54 | "float lumaNW = dot( rgbNW, luma );", 55 | "float lumaNE = dot( rgbNE, luma );", 56 | "float lumaSW = dot( rgbSW, luma );", 57 | "float lumaSE = dot( rgbSE, luma );", 58 | "float lumaM = dot( rgbM, luma );", 59 | "float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );", 60 | "float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );", 61 | 62 | "vec2 dir;", 63 | "dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));", 64 | "dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));", 65 | 66 | "float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );", 67 | 68 | "float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );", 69 | "dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),", 70 | "max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),", 71 | "dir * rcpDirMin)) * resolution;", 72 | "vec4 rgbA = (1.0/2.0) * (", 73 | "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (1.0/3.0 - 0.5)) +", 74 | "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (2.0/3.0 - 0.5)));", 75 | "vec4 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (", 76 | "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (0.0/3.0 - 0.5)) +", 77 | "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (3.0/3.0 - 0.5)));", 78 | "float lumaB = dot(rgbB, vec4(luma, 0.0));", 79 | 80 | "if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) {", 81 | 82 | "gl_FragColor = rgbA;", 83 | 84 | "} else {", 85 | "gl_FragColor = rgbB;", 86 | 87 | "}", 88 | 89 | "}" 90 | 91 | ].join("\n") 92 | 93 | }; 94 | -------------------------------------------------------------------------------- /js/libs/shaders/FilmShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Film grain & scanlines shader 5 | * 6 | * - ported from HLSL to WebGL / GLSL 7 | * http://www.truevision3d.com/forums/showcase/staticnoise_colorblackwhite_scanline_shaders-t18698.0.html 8 | * 9 | * Screen Space Static Postprocessor 10 | * 11 | * Produces an analogue noise overlay similar to a film grain / TV static 12 | * 13 | * Original implementation and noise algorithm 14 | * Pat 'Hawthorne' Shearon 15 | * 16 | * Optimized scanlines + noise version with intensity scaling 17 | * Georg 'Leviathan' Steinrohder 18 | * 19 | * This version is provided under a Creative Commons Attribution 3.0 License 20 | * http://creativecommons.org/licenses/by/3.0/ 21 | */ 22 | 23 | THREE.FilmShader = { 24 | 25 | uniforms: { 26 | 27 | "tDiffuse": { type: "t", value: null }, 28 | "time": { type: "f", value: 0.0 }, 29 | "nIntensity": { type: "f", value: 0.5 }, 30 | "sIntensity": { type: "f", value: 0.05 }, 31 | "sCount": { type: "f", value: 4096 }, 32 | "grayscale": { type: "i", value: 1 } 33 | 34 | }, 35 | 36 | vertexShader: [ 37 | 38 | "varying vec2 vUv;", 39 | 40 | "void main() {", 41 | 42 | "vUv = uv;", 43 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 44 | 45 | "}" 46 | 47 | ].join("\n"), 48 | 49 | fragmentShader: [ 50 | 51 | // control parameter 52 | "uniform float time;", 53 | 54 | "uniform bool grayscale;", 55 | 56 | // noise effect intensity value (0 = no effect, 1 = full effect) 57 | "uniform float nIntensity;", 58 | 59 | // scanlines effect intensity value (0 = no effect, 1 = full effect) 60 | "uniform float sIntensity;", 61 | 62 | // scanlines effect count value (0 = no effect, 4096 = full effect) 63 | "uniform float sCount;", 64 | 65 | "uniform sampler2D tDiffuse;", 66 | 67 | "varying vec2 vUv;", 68 | 69 | "void main() {", 70 | 71 | // sample the source 72 | "vec4 cTextureScreen = texture2D( tDiffuse, vUv );", 73 | 74 | // make some noise 75 | "float x = vUv.x * vUv.y * time * 1000.0;", 76 | "x = mod( x, 13.0 ) * mod( x, 123.0 );", 77 | "float dx = mod( x, 0.01 );", 78 | 79 | // add noise 80 | "vec3 cResult = cTextureScreen.rgb + cTextureScreen.rgb * clamp( 0.1 + dx * 100.0, 0.0, 1.0 );", 81 | 82 | // get us a sine and cosine 83 | "vec2 sc = vec2( sin( vUv.y * sCount ), cos( vUv.y * sCount ) );", 84 | 85 | // add scanlines 86 | "cResult += cTextureScreen.rgb * vec3( sc.x, sc.y, sc.x ) * sIntensity;", 87 | 88 | // interpolate between source and result by intensity 89 | "cResult = cTextureScreen.rgb + clamp( nIntensity, 0.0,1.0 ) * ( cResult - cTextureScreen.rgb );", 90 | 91 | // convert to grayscale if desired 92 | "if( grayscale ) {", 93 | 94 | "cResult = vec3( cResult.r * 0.3 + cResult.g * 0.59 + cResult.b * 0.11 );", 95 | 96 | "}", 97 | 98 | "gl_FragColor = vec4( cResult, cTextureScreen.a );", 99 | 100 | "}" 101 | 102 | ].join("\n") 103 | 104 | }; 105 | -------------------------------------------------------------------------------- /js/libs/shaders/FocusShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Focus shader 5 | * based on PaintEffect postprocess from ro.me 6 | * http://code.google.com/p/3-dreams-of-black/source/browse/deploy/js/effects/PaintEffect.js 7 | */ 8 | 9 | THREE.FocusShader = { 10 | 11 | uniforms : { 12 | 13 | "tDiffuse": { type: "t", value: null }, 14 | "screenWidth": { type: "f", value: 1024 }, 15 | "screenHeight": { type: "f", value: 1024 }, 16 | "sampleDistance": { type: "f", value: 0.94 }, 17 | "waveFactor": { type: "f", value: 0.00125 } 18 | 19 | }, 20 | 21 | vertexShader: [ 22 | 23 | "varying vec2 vUv;", 24 | 25 | "void main() {", 26 | 27 | "vUv = uv;", 28 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 29 | 30 | "}" 31 | 32 | ].join("\n"), 33 | 34 | fragmentShader: [ 35 | 36 | "uniform float screenWidth;", 37 | "uniform float screenHeight;", 38 | "uniform float sampleDistance;", 39 | "uniform float waveFactor;", 40 | 41 | "uniform sampler2D tDiffuse;", 42 | 43 | "varying vec2 vUv;", 44 | 45 | "void main() {", 46 | 47 | "vec4 color, org, tmp, add;", 48 | "float sample_dist, f;", 49 | "vec2 vin;", 50 | "vec2 uv = vUv;", 51 | 52 | "add = color = org = texture2D( tDiffuse, uv );", 53 | 54 | "vin = ( uv - vec2( 0.5 ) ) * vec2( 1.4 );", 55 | "sample_dist = dot( vin, vin ) * 2.0;", 56 | 57 | "f = ( waveFactor * 100.0 + sample_dist ) * sampleDistance * 4.0;", 58 | 59 | "vec2 sampleSize = vec2( 1.0 / screenWidth, 1.0 / screenHeight ) * vec2( f );", 60 | 61 | "add += tmp = texture2D( tDiffuse, uv + vec2( 0.111964, 0.993712 ) * sampleSize );", 62 | "if( tmp.b < color.b ) color = tmp;", 63 | 64 | "add += tmp = texture2D( tDiffuse, uv + vec2( 0.846724, 0.532032 ) * sampleSize );", 65 | "if( tmp.b < color.b ) color = tmp;", 66 | 67 | "add += tmp = texture2D( tDiffuse, uv + vec2( 0.943883, -0.330279 ) * sampleSize );", 68 | "if( tmp.b < color.b ) color = tmp;", 69 | 70 | "add += tmp = texture2D( tDiffuse, uv + vec2( 0.330279, -0.943883 ) * sampleSize );", 71 | "if( tmp.b < color.b ) color = tmp;", 72 | 73 | "add += tmp = texture2D( tDiffuse, uv + vec2( -0.532032, -0.846724 ) * sampleSize );", 74 | "if( tmp.b < color.b ) color = tmp;", 75 | 76 | "add += tmp = texture2D( tDiffuse, uv + vec2( -0.993712, -0.111964 ) * sampleSize );", 77 | "if( tmp.b < color.b ) color = tmp;", 78 | 79 | "add += tmp = texture2D( tDiffuse, uv + vec2( -0.707107, 0.707107 ) * sampleSize );", 80 | "if( tmp.b < color.b ) color = tmp;", 81 | 82 | "color = color * vec4( 2.0 ) - ( add / vec4( 8.0 ) );", 83 | "color = color + ( add / vec4( 8.0 ) - color ) * ( vec4( 1.0 ) - vec4( sample_dist * 0.5 ) );", 84 | 85 | "gl_FragColor = vec4( color.rgb * color.rgb * vec3( 0.95 ) + color.rgb, 1.0 );", 86 | 87 | "}" 88 | 89 | 90 | ].join("\n") 91 | }; 92 | -------------------------------------------------------------------------------- /js/libs/shaders/FresnelShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Based on Nvidia Cg tutorial 5 | */ 6 | 7 | THREE.FresnelShader = { 8 | 9 | uniforms: { 10 | 11 | "mRefractionRatio": { type: "f", value: 1.02 }, 12 | "mFresnelBias": { type: "f", value: 0.1 }, 13 | "mFresnelPower": { type: "f", value: 2.0 }, 14 | "mFresnelScale": { type: "f", value: 1.0 }, 15 | "tCube": { type: "t", value: null } 16 | 17 | }, 18 | 19 | vertexShader: [ 20 | 21 | "uniform float mRefractionRatio;", 22 | "uniform float mFresnelBias;", 23 | "uniform float mFresnelScale;", 24 | "uniform float mFresnelPower;", 25 | 26 | "varying vec3 vReflect;", 27 | "varying vec3 vRefract[3];", 28 | "varying float vReflectionFactor;", 29 | 30 | "void main() {", 31 | 32 | "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", 33 | "vec4 worldPosition = modelMatrix * vec4( position, 1.0 );", 34 | 35 | "vec3 worldNormal = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );", 36 | 37 | "vec3 I = worldPosition.xyz - cameraPosition;", 38 | 39 | "vReflect = reflect( I, worldNormal );", 40 | "vRefract[0] = refract( normalize( I ), worldNormal, mRefractionRatio );", 41 | "vRefract[1] = refract( normalize( I ), worldNormal, mRefractionRatio * 0.99 );", 42 | "vRefract[2] = refract( normalize( I ), worldNormal, mRefractionRatio * 0.98 );", 43 | "vReflectionFactor = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( I ), worldNormal ), mFresnelPower );", 44 | 45 | "gl_Position = projectionMatrix * mvPosition;", 46 | 47 | "}" 48 | 49 | ].join("\n"), 50 | 51 | fragmentShader: [ 52 | 53 | "uniform samplerCube tCube;", 54 | 55 | "varying vec3 vReflect;", 56 | "varying vec3 vRefract[3];", 57 | "varying float vReflectionFactor;", 58 | 59 | "void main() {", 60 | 61 | "vec4 reflectedColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );", 62 | "vec4 refractedColor = vec4( 1.0 );", 63 | 64 | "refractedColor.r = textureCube( tCube, vec3( -vRefract[0].x, vRefract[0].yz ) ).r;", 65 | "refractedColor.g = textureCube( tCube, vec3( -vRefract[1].x, vRefract[1].yz ) ).g;", 66 | "refractedColor.b = textureCube( tCube, vec3( -vRefract[2].x, vRefract[2].yz ) ).b;", 67 | 68 | "gl_FragColor = mix( refractedColor, reflectedColor, clamp( vReflectionFactor, 0.0, 1.0 ) );", 69 | 70 | "}" 71 | 72 | ].join("\n") 73 | 74 | }; 75 | -------------------------------------------------------------------------------- /js/libs/shaders/HorizontalBlurShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author zz85 / http://www.lab4games.net/zz85/blog 3 | * 4 | * Two pass Gaussian blur filter (horizontal and vertical blur shaders) 5 | * - described in http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/ 6 | * and used in http://www.cake23.de/traveling-wavefronts-lit-up.html 7 | * 8 | * - 9 samples per pass 9 | * - standard deviation 2.7 10 | * - "h" and "v" parameters should be set to "1 / width" and "1 / height" 11 | */ 12 | 13 | THREE.HorizontalBlurShader = { 14 | 15 | uniforms: { 16 | 17 | "tDiffuse": { type: "t", value: null }, 18 | "h": { type: "f", value: 1.0 / 512.0 } 19 | 20 | }, 21 | 22 | vertexShader: [ 23 | 24 | "varying vec2 vUv;", 25 | 26 | "void main() {", 27 | 28 | "vUv = uv;", 29 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 30 | 31 | "}" 32 | 33 | ].join("\n"), 34 | 35 | fragmentShader: [ 36 | 37 | "uniform sampler2D tDiffuse;", 38 | "uniform float h;", 39 | 40 | "varying vec2 vUv;", 41 | 42 | "void main() {", 43 | 44 | "vec4 sum = vec4( 0.0 );", 45 | 46 | "sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * h, vUv.y ) ) * 0.051;", 47 | "sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * h, vUv.y ) ) * 0.0918;", 48 | "sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * h, vUv.y ) ) * 0.12245;", 49 | "sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * h, vUv.y ) ) * 0.1531;", 50 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", 51 | "sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * h, vUv.y ) ) * 0.1531;", 52 | "sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * h, vUv.y ) ) * 0.12245;", 53 | "sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * h, vUv.y ) ) * 0.0918;", 54 | "sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * h, vUv.y ) ) * 0.051;", 55 | 56 | "gl_FragColor = sum;", 57 | 58 | "}" 59 | 60 | ].join("\n") 61 | 62 | }; 63 | -------------------------------------------------------------------------------- /js/libs/shaders/HorizontalTiltShiftShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Simple fake tilt-shift effect, modulating two pass Gaussian blur (see above) by vertical position 5 | * 6 | * - 9 samples per pass 7 | * - standard deviation 2.7 8 | * - "h" and "v" parameters should be set to "1 / width" and "1 / height" 9 | * - "r" parameter control where "focused" horizontal line lies 10 | */ 11 | 12 | THREE.HorizontalTiltShiftShader = { 13 | 14 | uniforms: { 15 | 16 | "tDiffuse": { type: "t", value: null }, 17 | "h": { type: "f", value: 1.0 / 512.0 }, 18 | "r": { type: "f", value: 0.35 } 19 | 20 | }, 21 | 22 | vertexShader: [ 23 | 24 | "varying vec2 vUv;", 25 | 26 | "void main() {", 27 | 28 | "vUv = uv;", 29 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 30 | 31 | "}" 32 | 33 | ].join("\n"), 34 | 35 | fragmentShader: [ 36 | 37 | "uniform sampler2D tDiffuse;", 38 | "uniform float h;", 39 | "uniform float r;", 40 | 41 | "varying vec2 vUv;", 42 | 43 | "void main() {", 44 | 45 | "vec4 sum = vec4( 0.0 );", 46 | 47 | "float hh = h * abs( r - vUv.y );", 48 | 49 | "sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * hh, vUv.y ) ) * 0.051;", 50 | "sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * hh, vUv.y ) ) * 0.0918;", 51 | "sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * hh, vUv.y ) ) * 0.12245;", 52 | "sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * hh, vUv.y ) ) * 0.1531;", 53 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", 54 | "sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * hh, vUv.y ) ) * 0.1531;", 55 | "sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * hh, vUv.y ) ) * 0.12245;", 56 | "sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * hh, vUv.y ) ) * 0.0918;", 57 | "sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * hh, vUv.y ) ) * 0.051;", 58 | 59 | "gl_FragColor = sum;", 60 | 61 | "}" 62 | 63 | ].join("\n") 64 | 65 | }; 66 | -------------------------------------------------------------------------------- /js/libs/shaders/HueSaturationShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author tapio / http://tapio.github.com/ 3 | * 4 | * Hue and saturation adjustment 5 | * https://github.com/evanw/glfx.js 6 | * hue: -1 to 1 (-1 is 180 degrees in the negative direction, 0 is no change, etc. 7 | * saturation: -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast) 8 | */ 9 | 10 | THREE.HueSaturationShader = { 11 | 12 | uniforms: { 13 | 14 | "tDiffuse": { type: "t", value: null }, 15 | "hue": { type: "f", value: 0 }, 16 | "saturation": { type: "f", value: 0 } 17 | 18 | }, 19 | 20 | vertexShader: [ 21 | 22 | "varying vec2 vUv;", 23 | 24 | "void main() {", 25 | 26 | "vUv = uv;", 27 | 28 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 29 | 30 | "}" 31 | 32 | ].join("\n"), 33 | 34 | fragmentShader: [ 35 | 36 | "uniform sampler2D tDiffuse;", 37 | "uniform float hue;", 38 | "uniform float saturation;", 39 | 40 | "varying vec2 vUv;", 41 | 42 | "void main() {", 43 | 44 | "gl_FragColor = texture2D( tDiffuse, vUv );", 45 | 46 | // hue 47 | "float angle = hue * 3.14159265;", 48 | "float s = sin(angle), c = cos(angle);", 49 | "vec3 weights = (vec3(2.0 * c, -sqrt(3.0) * s - c, sqrt(3.0) * s - c) + 1.0) / 3.0;", 50 | "float len = length(gl_FragColor.rgb);", 51 | "gl_FragColor.rgb = vec3(", 52 | "dot(gl_FragColor.rgb, weights.xyz),", 53 | "dot(gl_FragColor.rgb, weights.zxy),", 54 | "dot(gl_FragColor.rgb, weights.yzx)", 55 | ");", 56 | 57 | // saturation 58 | "float average = (gl_FragColor.r + gl_FragColor.g + gl_FragColor.b) / 3.0;", 59 | "if (saturation > 0.0) {", 60 | "gl_FragColor.rgb += (average - gl_FragColor.rgb) * (1.0 - 1.0 / (1.001 - saturation));", 61 | "} else {", 62 | "gl_FragColor.rgb += (average - gl_FragColor.rgb) * (-saturation);", 63 | "}", 64 | 65 | "}" 66 | 67 | ].join("\n") 68 | 69 | }; 70 | -------------------------------------------------------------------------------- /js/libs/shaders/KaleidoShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author felixturner / http://airtight.cc/ 3 | * 4 | * Kaleidoscope Shader 5 | * Radial reflection around center point 6 | * Ported from: http://pixelshaders.com/editor/ 7 | * by Toby Schachman / http://tobyschachman.com/ 8 | * 9 | * sides: number of reflections 10 | * angle: initial angle in radians 11 | */ 12 | 13 | THREE.KaleidoShader = { 14 | 15 | uniforms: { 16 | 17 | "tDiffuse": { type: "t", value: null }, 18 | "sides": { type: "f", value: 6.0 }, 19 | "angle": { type: "f", value: 0.0 } 20 | 21 | }, 22 | 23 | vertexShader: [ 24 | 25 | "varying vec2 vUv;", 26 | 27 | "void main() {", 28 | 29 | "vUv = uv;", 30 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 31 | 32 | "}" 33 | 34 | ].join("\n"), 35 | 36 | fragmentShader: [ 37 | 38 | "uniform sampler2D tDiffuse;", 39 | "uniform float sides;", 40 | "uniform float angle;", 41 | 42 | "varying vec2 vUv;", 43 | 44 | "void main() {", 45 | 46 | "vec2 p = vUv - 0.5;", 47 | "float r = length(p);", 48 | "float a = atan(p.y, p.x) + angle;", 49 | "float tau = 2. * 3.1416 ;", 50 | "a = mod(a, tau/sides);", 51 | "a = abs(a - tau/sides/2.) ;", 52 | "p = r * vec2(cos(a), sin(a));", 53 | "vec4 color = texture2D(tDiffuse, p + 0.5);", 54 | "gl_FragColor = color;", 55 | 56 | "}" 57 | 58 | ].join("\n") 59 | 60 | }; 61 | -------------------------------------------------------------------------------- /js/libs/shaders/LuminosityShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Luminosity 5 | * http://en.wikipedia.org/wiki/Luminosity 6 | */ 7 | 8 | THREE.LuminosityShader = { 9 | 10 | uniforms: { 11 | 12 | "tDiffuse": { type: "t", value: null } 13 | 14 | }, 15 | 16 | vertexShader: [ 17 | 18 | "varying vec2 vUv;", 19 | 20 | "void main() {", 21 | 22 | "vUv = uv;", 23 | 24 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 25 | 26 | "}" 27 | 28 | ].join("\n"), 29 | 30 | fragmentShader: [ 31 | 32 | "uniform sampler2D tDiffuse;", 33 | 34 | "varying vec2 vUv;", 35 | 36 | "void main() {", 37 | 38 | "vec4 texel = texture2D( tDiffuse, vUv );", 39 | 40 | "vec3 luma = vec3( 0.299, 0.587, 0.114 );", 41 | 42 | "float v = dot( texel.xyz, luma );", 43 | 44 | "gl_FragColor = vec4( v, v, v, texel.w );", 45 | 46 | "}" 47 | 48 | ].join("\n") 49 | 50 | }; 51 | -------------------------------------------------------------------------------- /js/libs/shaders/MirrorShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author felixturner / http://airtight.cc/ 3 | * 4 | * Mirror Shader 5 | * Copies half the input to the other half 6 | * 7 | * side: side of input to mirror (0 = left, 1 = right, 2 = top, 3 = bottom) 8 | */ 9 | 10 | THREE.MirrorShader = { 11 | 12 | uniforms: { 13 | 14 | "tDiffuse": { type: "t", value: null }, 15 | "side": { type: "i", value: 1 } 16 | 17 | }, 18 | 19 | vertexShader: [ 20 | 21 | "varying vec2 vUv;", 22 | 23 | "void main() {", 24 | 25 | "vUv = uv;", 26 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 27 | 28 | "}" 29 | 30 | ].join("\n"), 31 | 32 | fragmentShader: [ 33 | 34 | "uniform sampler2D tDiffuse;", 35 | "uniform int side;", 36 | 37 | "varying vec2 vUv;", 38 | 39 | "void main() {", 40 | 41 | "vec2 p = vUv;", 42 | "if (side == 0){", 43 | "if (p.x > 0.5) p.x = 1.0 - p.x;", 44 | "}else if (side == 1){", 45 | "if (p.x < 0.5) p.x = 1.0 - p.x;", 46 | "}else if (side == 2){", 47 | "if (p.y < 0.5) p.y = 1.0 - p.y;", 48 | "}else if (side == 3){", 49 | "if (p.y > 0.5) p.y = 1.0 - p.y;", 50 | "} ", 51 | "vec4 color = texture2D(tDiffuse, p);", 52 | "gl_FragColor = color;", 53 | 54 | "}" 55 | 56 | ].join("\n") 57 | 58 | }; 59 | -------------------------------------------------------------------------------- /js/libs/shaders/NormalMapShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Normal map shader 5 | * - compute normals from heightmap 6 | */ 7 | 8 | THREE.NormalMapShader = { 9 | 10 | uniforms: { 11 | 12 | "heightMap": { type: "t", value: null }, 13 | "resolution": { type: "v2", value: new THREE.Vector2( 512, 512 ) }, 14 | "scale": { type: "v2", value: new THREE.Vector2( 1, 1 ) }, 15 | "height": { type: "f", value: 0.05 } 16 | 17 | }, 18 | 19 | vertexShader: [ 20 | 21 | "varying vec2 vUv;", 22 | 23 | "void main() {", 24 | 25 | "vUv = uv;", 26 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 27 | 28 | "}" 29 | 30 | ].join("\n"), 31 | 32 | fragmentShader: [ 33 | 34 | "uniform float height;", 35 | "uniform vec2 resolution;", 36 | "uniform sampler2D heightMap;", 37 | 38 | "varying vec2 vUv;", 39 | 40 | "void main() {", 41 | 42 | "float val = texture2D( heightMap, vUv ).x;", 43 | 44 | "float valU = texture2D( heightMap, vUv + vec2( 1.0 / resolution.x, 0.0 ) ).x;", 45 | "float valV = texture2D( heightMap, vUv + vec2( 0.0, 1.0 / resolution.y ) ).x;", 46 | 47 | "gl_FragColor = vec4( ( 0.5 * normalize( vec3( val - valU, val - valV, height ) ) + 0.5 ), 1.0 );", 48 | 49 | "}" 50 | 51 | ].join("\n") 52 | 53 | }; 54 | -------------------------------------------------------------------------------- /js/libs/shaders/OceanShaders.js: -------------------------------------------------------------------------------- 1 | // Author: Aleksandr Albert 2 | // Website: www.routter.co.tt 3 | 4 | // Description: A deep water ocean shader set 5 | // based on an implementation of a Tessendorf Waves 6 | // originally presented by David Li ( www.david.li/waves ) 7 | 8 | // The general method is to apply shaders to simulation Framebuffers 9 | // and then sample these framebuffers when rendering the ocean mesh 10 | 11 | // The set uses 7 shaders: 12 | 13 | // -- Simulation shaders 14 | // [1] ocean_sim_vertex -> Vertex shader used to set up a 2x2 simulation plane centered at (0,0) 15 | // [2] ocean_subtransform -> Fragment shader used to subtransform the mesh (generates the displacement map) 16 | // [3] ocean_initial_spectrum -> Fragment shader used to set intitial wave frequency at a texel coordinate 17 | // [4] ocean_phase -> Fragment shader used to set wave phase at a texel coordinate 18 | // [5] ocean_spectrum -> Fragment shader used to set current wave frequency at a texel coordinate 19 | // [6] ocean_normal -> Fragment shader used to set face normals at a texel coordinate 20 | 21 | // -- Rendering Shader 22 | // [7] ocean_main -> Vertex and Fragment shader used to create the final render 23 | 24 | 25 | THREE.ShaderLib['ocean_sim_vertex'] = { 26 | varying: { 27 | "vUV": { type: "v2" } 28 | }, 29 | vertexShader: [ 30 | 'varying vec2 vUV;', 31 | 32 | 'void main (void) {', 33 | 'vUV = position.xy * 0.5 + 0.5;', 34 | 'gl_Position = vec4(position, 1.0 );', 35 | '}' 36 | ].join('\n') 37 | }; 38 | THREE.ShaderLib['ocean_subtransform'] = { 39 | uniforms: { 40 | "u_input": { type: "t", value: null }, 41 | "u_transformSize": { type: "f", value: 512.0 }, 42 | "u_subtransformSize": { type: "f", value: 250.0 } 43 | }, 44 | varying: { 45 | "vUV": { type: "v2" } 46 | }, 47 | fragmentShader: [ 48 | //GPU FFT using a Stockham formulation 49 | 'precision highp float;', 50 | 51 | 'const float PI = 3.14159265359;', 52 | 53 | 'uniform sampler2D u_input;', 54 | 'uniform float u_transformSize;', 55 | 'uniform float u_subtransformSize;', 56 | 57 | 'varying vec2 vUV;', 58 | 59 | 'vec2 multiplyComplex (vec2 a, vec2 b) {', 60 | 'return vec2(a[0] * b[0] - a[1] * b[1], a[1] * b[0] + a[0] * b[1]);', 61 | '}', 62 | 63 | 'void main (void) {', 64 | '#ifdef HORIZONTAL', 65 | 'float index = vUV.x * u_transformSize - 0.5;', 66 | '#else', 67 | 'float index = vUV.y * u_transformSize - 0.5;', 68 | '#endif', 69 | 70 | 'float evenIndex = floor(index / u_subtransformSize) * (u_subtransformSize * 0.5) + mod(index, u_subtransformSize * 0.5);', 71 | 72 | //transform two complex sequences simultaneously 73 | '#ifdef HORIZONTAL', 74 | 'vec4 even = texture2D(u_input, vec2(evenIndex + 0.5, gl_FragCoord.y) / u_transformSize).rgba;', 75 | 'vec4 odd = texture2D(u_input, vec2(evenIndex + u_transformSize * 0.5 + 0.5, gl_FragCoord.y) / u_transformSize).rgba;', 76 | '#else', 77 | 'vec4 even = texture2D(u_input, vec2(gl_FragCoord.x, evenIndex + 0.5) / u_transformSize).rgba;', 78 | 'vec4 odd = texture2D(u_input, vec2(gl_FragCoord.x, evenIndex + u_transformSize * 0.5 + 0.5) / u_transformSize).rgba;', 79 | '#endif', 80 | 81 | 'float twiddleArgument = -2.0 * PI * (index / u_subtransformSize);', 82 | 'vec2 twiddle = vec2(cos(twiddleArgument), sin(twiddleArgument));', 83 | 84 | 'vec2 outputA = even.xy + multiplyComplex(twiddle, odd.xy);', 85 | 'vec2 outputB = even.zw + multiplyComplex(twiddle, odd.zw);', 86 | 87 | 'gl_FragColor = vec4(outputA, outputB);', 88 | '}' 89 | ].join('\n') 90 | }; 91 | THREE.ShaderLib['ocean_initial_spectrum'] = { 92 | uniforms: { 93 | "u_wind": { type: "v2", value: new THREE.Vector2(10.0, 10.0) }, 94 | "u_resolution": { type: "f", value: 512.0 }, 95 | "u_size": { type: "f", value: 250.0 }, 96 | }, 97 | fragmentShader: [ 98 | 'precision highp float;', 99 | 100 | 'const float PI = 3.14159265359;', 101 | 'const float G = 9.81;', 102 | 'const float KM = 370.0;', 103 | 'const float CM = 0.23;', 104 | 105 | 'uniform vec2 u_wind;', 106 | 'uniform float u_resolution;', 107 | 'uniform float u_size;', 108 | 109 | 'float square (float x) {', 110 | 'return x * x;', 111 | '}', 112 | 113 | 'float omega (float k) {', 114 | 'return sqrt(G * k * (1.0 + square(k / KM)));', 115 | '}', 116 | 117 | 'float tanh (float x) {', 118 | 'return (1.0 - exp(-2.0 * x)) / (1.0 + exp(-2.0 * x));', 119 | '}', 120 | 121 | 'void main (void) {', 122 | 'vec2 coordinates = gl_FragCoord.xy - 0.5;', 123 | 124 | 'float n = (coordinates.x < u_resolution * 0.5) ? coordinates.x : coordinates.x - u_resolution;', 125 | 'float m = (coordinates.y < u_resolution * 0.5) ? coordinates.y : coordinates.y - u_resolution;', 126 | 127 | 'vec2 K = (2.0 * PI * vec2(n, m)) / u_size;', 128 | 'float k = length(K);', 129 | 130 | 'float l_wind = length(u_wind);', 131 | 132 | 'float Omega = 0.84;', 133 | 'float kp = G * square(Omega / l_wind);', 134 | 135 | 'float c = omega(k) / k;', 136 | 'float cp = omega(kp) / kp;', 137 | 138 | 'float Lpm = exp(-1.25 * square(kp / k));', 139 | 'float gamma = 1.7;', 140 | 'float sigma = 0.08 * (1.0 + 4.0 * pow(Omega, -3.0));', 141 | 'float Gamma = exp(-square(sqrt(k / kp) - 1.0) / 2.0 * square(sigma));', 142 | 'float Jp = pow(gamma, Gamma);', 143 | 'float Fp = Lpm * Jp * exp(-Omega / sqrt(10.0) * (sqrt(k / kp) - 1.0));', 144 | 'float alphap = 0.006 * sqrt(Omega);', 145 | 'float Bl = 0.5 * alphap * cp / c * Fp;', 146 | 147 | 'float z0 = 0.000037 * square(l_wind) / G * pow(l_wind / cp, 0.9);', 148 | 'float uStar = 0.41 * l_wind / log(10.0 / z0);', 149 | 'float alpham = 0.01 * ((uStar < CM) ? (1.0 + log(uStar / CM)) : (1.0 + 3.0 * log(uStar / CM)));', 150 | 'float Fm = exp(-0.25 * square(k / KM - 1.0));', 151 | 'float Bh = 0.5 * alpham * CM / c * Fm * Lpm;', 152 | 153 | 'float a0 = log(2.0) / 4.0;', 154 | 'float am = 0.13 * uStar / CM;', 155 | 'float Delta = tanh(a0 + 4.0 * pow(c / cp, 2.5) + am * pow(CM / c, 2.5));', 156 | 157 | 'float cosPhi = dot(normalize(u_wind), normalize(K));', 158 | 159 | 'float S = (1.0 / (2.0 * PI)) * pow(k, -4.0) * (Bl + Bh) * (1.0 + Delta * (2.0 * cosPhi * cosPhi - 1.0));', 160 | 161 | 'float dk = 2.0 * PI / u_size;', 162 | 'float h = sqrt(S / 2.0) * dk;', 163 | 164 | 'if (K.x == 0.0 && K.y == 0.0) {', 165 | 'h = 0.0;', //no DC term 166 | '}', 167 | 'gl_FragColor = vec4(h, 0.0, 0.0, 0.0);', 168 | '}' 169 | ].join('\n') 170 | }; 171 | THREE.ShaderLib['ocean_phase'] = { 172 | uniforms: { 173 | "u_phases": { type: "t", value: null }, 174 | "u_deltaTime": { type: "f", value: null }, 175 | "u_resolution": { type: "f", value: null }, 176 | "u_size": { type: "f", value: null }, 177 | }, 178 | varying: { 179 | "vUV": { type: "v2" } 180 | }, 181 | fragmentShader: [ 182 | 'precision highp float;', 183 | 184 | 'const float PI = 3.14159265359;', 185 | 'const float G = 9.81;', 186 | 'const float KM = 370.0;', 187 | 188 | 'varying vec2 vUV;', 189 | 190 | 'uniform sampler2D u_phases;', 191 | 'uniform float u_deltaTime;', 192 | 'uniform float u_resolution;', 193 | 'uniform float u_size;', 194 | 195 | 'float omega (float k) {', 196 | 'return sqrt(G * k * (1.0 + k * k / KM * KM));', 197 | '}', 198 | 199 | 'void main (void) {', 200 | 'float deltaTime = 1.0 / 60.0;', 201 | 'vec2 coordinates = gl_FragCoord.xy - 0.5;', 202 | 'float n = (coordinates.x < u_resolution * 0.5) ? coordinates.x : coordinates.x - u_resolution;', 203 | 'float m = (coordinates.y < u_resolution * 0.5) ? coordinates.y : coordinates.y - u_resolution;', 204 | 'vec2 waveVector = (2.0 * PI * vec2(n, m)) / u_size;', 205 | 206 | 'float phase = texture2D(u_phases, vUV).r;', 207 | 'float deltaPhase = omega(length(waveVector)) * u_deltaTime;', 208 | 'phase = mod(phase + deltaPhase, 2.0 * PI);', 209 | 210 | 'gl_FragColor = vec4(phase, 0.0, 0.0, 0.0);', 211 | '}' 212 | ].join('\n') 213 | }; 214 | THREE.ShaderLib['ocean_spectrum'] = { 215 | uniforms: { 216 | "u_size": { type: "f", value: null }, 217 | "u_resolution": { type: "f", value: null }, 218 | "u_choppiness": { type: "f", value: null }, 219 | "u_phases": { type: "t", value: null }, 220 | "u_initialSpectrum": { type: "t", value: null }, 221 | }, 222 | varying: { 223 | "vUV": { type: "v2" } 224 | }, 225 | fragmentShader: [ 226 | 'precision highp float;', 227 | 228 | 'const float PI = 3.14159265359;', 229 | 'const float G = 9.81;', 230 | 'const float KM = 370.0;', 231 | 232 | 'varying vec2 vUV;', 233 | 234 | 'uniform float u_size;', 235 | 'uniform float u_resolution;', 236 | 'uniform float u_choppiness;', 237 | 'uniform sampler2D u_phases;', 238 | 'uniform sampler2D u_initialSpectrum;', 239 | 240 | 'vec2 multiplyComplex (vec2 a, vec2 b) {', 241 | 'return vec2(a[0] * b[0] - a[1] * b[1], a[1] * b[0] + a[0] * b[1]);', 242 | '}', 243 | 244 | 'vec2 multiplyByI (vec2 z) {', 245 | 'return vec2(-z[1], z[0]);', 246 | '}', 247 | 248 | 'float omega (float k) {', 249 | 'return sqrt(G * k * (1.0 + k * k / KM * KM));', 250 | '}', 251 | 252 | 'void main (void) {', 253 | 'vec2 coordinates = gl_FragCoord.xy - 0.5;', 254 | 'float n = (coordinates.x < u_resolution * 0.5) ? coordinates.x : coordinates.x - u_resolution;', 255 | 'float m = (coordinates.y < u_resolution * 0.5) ? coordinates.y : coordinates.y - u_resolution;', 256 | 'vec2 waveVector = (2.0 * PI * vec2(n, m)) / u_size;', 257 | 258 | 'float phase = texture2D(u_phases, vUV).r;', 259 | 'vec2 phaseVector = vec2(cos(phase), sin(phase));', 260 | 261 | 'vec2 h0 = texture2D(u_initialSpectrum, vUV).rg;', 262 | 'vec2 h0Star = texture2D(u_initialSpectrum, vec2(1.0 - vUV + 1.0 / u_resolution)).rg;', 263 | 'h0Star.y *= -1.0;', 264 | 265 | 'vec2 h = multiplyComplex(h0, phaseVector) + multiplyComplex(h0Star, vec2(phaseVector.x, -phaseVector.y));', 266 | 267 | 'vec2 hX = -multiplyByI(h * (waveVector.x / length(waveVector))) * u_choppiness;', 268 | 'vec2 hZ = -multiplyByI(h * (waveVector.y / length(waveVector))) * u_choppiness;', 269 | 270 | //no DC term 271 | 'if (waveVector.x == 0.0 && waveVector.y == 0.0) {', 272 | 'h = vec2(0.0);', 273 | 'hX = vec2(0.0);', 274 | 'hZ = vec2(0.0);', 275 | '}', 276 | 277 | 'gl_FragColor = vec4(hX + multiplyByI(h), hZ);', 278 | '}' 279 | ].join('\n') 280 | }; 281 | THREE.ShaderLib['ocean_normals'] = { 282 | uniforms: { 283 | "u_displacementMap": { type: "t", value: null }, 284 | "u_resolution": { type: "f", value: null }, 285 | "u_size": { type: "f", value: null }, 286 | }, 287 | varying: { 288 | "vUV": { type: "v2" } 289 | }, 290 | fragmentShader: [ 291 | 'precision highp float;', 292 | 293 | 'varying vec2 vUV;', 294 | 295 | 'uniform sampler2D u_displacementMap;', 296 | 'uniform float u_resolution;', 297 | 'uniform float u_size;', 298 | 299 | 'void main (void) {', 300 | 'float texel = 1.0 / u_resolution;', 301 | 'float texelSize = u_size / u_resolution;', 302 | 303 | 'vec3 center = texture2D(u_displacementMap, vUV).rgb;', 304 | 'vec3 right = vec3(texelSize, 0.0, 0.0) + texture2D(u_displacementMap, vUV + vec2(texel, 0.0)).rgb - center;', 305 | 'vec3 left = vec3(-texelSize, 0.0, 0.0) + texture2D(u_displacementMap, vUV + vec2(-texel, 0.0)).rgb - center;', 306 | 'vec3 top = vec3(0.0, 0.0, -texelSize) + texture2D(u_displacementMap, vUV + vec2(0.0, -texel)).rgb - center;', 307 | 'vec3 bottom = vec3(0.0, 0.0, texelSize) + texture2D(u_displacementMap, vUV + vec2(0.0, texel)).rgb - center;', 308 | 309 | 'vec3 topRight = cross(right, top);', 310 | 'vec3 topLeft = cross(top, left);', 311 | 'vec3 bottomLeft = cross(left, bottom);', 312 | 'vec3 bottomRight = cross(bottom, right);', 313 | 314 | 'gl_FragColor = vec4(normalize(topRight + topLeft + bottomLeft + bottomRight), 1.0);', 315 | '}' 316 | ].join('\n') 317 | }; 318 | THREE.ShaderLib['ocean_main'] = { 319 | uniforms: { 320 | "u_displacementMap": { type: "t", value: null }, 321 | "u_normalMap": { type: "t", value: null }, 322 | "u_geometrySize": { type: "f", value: null }, 323 | "u_size": { type: "f", value: null }, 324 | "u_projectionMatrix": { type: "m4", value: null }, 325 | "u_viewMatrix": { type: "m4", value: null }, 326 | "u_cameraPosition": { type: "v3", value: null }, 327 | "u_skyColor": { type: "v3", value: null }, 328 | "u_oceanColor": { type: "v3", value: null }, 329 | "u_sunDirection": { type: "v3", value: null }, 330 | "u_exposure": { type: "f", value: null }, 331 | }, 332 | varying: { 333 | "vPos": { type: "v3" }, 334 | "vUV": { type: "v2" } 335 | }, 336 | vertexShader: [ 337 | 'precision highp float;', 338 | 339 | 'varying vec3 vPos;', 340 | 'varying vec2 vUV;', 341 | 342 | 'uniform mat4 u_projectionMatrix;', 343 | 'uniform mat4 u_viewMatrix;', 344 | 'uniform float u_size;', 345 | 'uniform float u_geometrySize;', 346 | 'uniform sampler2D u_displacementMap;', 347 | 348 | 'void main (void) {', 349 | 'vec3 newPos = position + texture2D(u_displacementMap, uv).rgb * (u_geometrySize / u_size);', 350 | 'vPos = newPos;', 351 | 'vUV = uv;', 352 | 'gl_Position = u_projectionMatrix * u_viewMatrix * vec4(newPos, 1.0);', 353 | '}' 354 | ].join('\n'), 355 | fragmentShader: [ 356 | 'precision highp float;', 357 | 358 | 'varying vec3 vPos;', 359 | 'varying vec2 vUV;', 360 | 361 | 'uniform sampler2D u_displacementMap;', 362 | 'uniform sampler2D u_normalMap;', 363 | 'uniform vec3 u_cameraPosition;', 364 | 'uniform vec3 u_oceanColor;', 365 | 'uniform vec3 u_skyColor;', 366 | 'uniform vec3 u_sunDirection;', 367 | 'uniform float u_exposure;', 368 | 369 | 'vec3 hdr (vec3 color, float exposure) {', 370 | 'return 1.0 - exp(-color * exposure);', 371 | '}', 372 | 373 | 'void main (void) {', 374 | 'vec3 normal = texture2D(u_normalMap, vUV).rgb;', 375 | 376 | 'vec3 view = normalize(u_cameraPosition - vPos);', 377 | 'float fresnel = 0.02 + 0.98 * pow(1.0 - dot(normal, view), 5.0);', 378 | 'vec3 sky = fresnel * u_skyColor;', 379 | 380 | 'float diffuse = clamp(dot(normal, normalize(u_sunDirection)), 0.0, 1.0);', 381 | 'vec3 water = (1.0 - fresnel) * u_oceanColor * u_skyColor * diffuse;', 382 | 383 | 'vec3 color = sky + water;', 384 | 385 | 'gl_FragColor = vec4(hdr(color, u_exposure), 1.0);', 386 | '}' 387 | ].join('\n') 388 | }; -------------------------------------------------------------------------------- /js/libs/shaders/RGBShiftShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author felixturner / http://airtight.cc/ 3 | * 4 | * RGB Shift Shader 5 | * Shifts red and blue channels from center in opposite directions 6 | * Ported from http://kriss.cx/tom/2009/05/rgb-shift/ 7 | * by Tom Butterworth / http://kriss.cx/tom/ 8 | * 9 | * amount: shift distance (1 is width of input) 10 | * angle: shift angle in radians 11 | */ 12 | 13 | THREE.RGBShiftShader = { 14 | 15 | uniforms: { 16 | 17 | "tDiffuse": { type: "t", value: null }, 18 | "amount": { type: "f", value: 0.005 }, 19 | "angle": { type: "f", value: 0.0 } 20 | 21 | }, 22 | 23 | vertexShader: [ 24 | 25 | "varying vec2 vUv;", 26 | 27 | "void main() {", 28 | 29 | "vUv = uv;", 30 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 31 | 32 | "}" 33 | 34 | ].join("\n"), 35 | 36 | fragmentShader: [ 37 | 38 | "uniform sampler2D tDiffuse;", 39 | "uniform float amount;", 40 | "uniform float angle;", 41 | 42 | "varying vec2 vUv;", 43 | 44 | "void main() {", 45 | 46 | "vec2 offset = amount * vec2( cos(angle), sin(angle));", 47 | "vec4 cr = texture2D(tDiffuse, vUv + offset);", 48 | "vec4 cga = texture2D(tDiffuse, vUv);", 49 | "vec4 cb = texture2D(tDiffuse, vUv - offset);", 50 | "gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);", 51 | 52 | "}" 53 | 54 | ].join("\n") 55 | 56 | }; 57 | -------------------------------------------------------------------------------- /js/libs/shaders/SSAOShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Screen-space ambient occlusion shader 5 | * - ported from 6 | * SSAO GLSL shader v1.2 7 | * assembled by Martins Upitis (martinsh) (http://devlog-martinsh.blogspot.com) 8 | * original technique is made by ArKano22 (http://www.gamedev.net/topic/550699-ssao-no-halo-artifacts/) 9 | * - modifications 10 | * - modified to use RGBA packed depth texture (use clear color 1,1,1,1 for depth pass) 11 | * - refactoring and optimizations 12 | */ 13 | 14 | THREE.SSAOShader = { 15 | 16 | uniforms: { 17 | 18 | "tDiffuse": { type: "t", value: null }, 19 | "tDepth": { type: "t", value: null }, 20 | "size": { type: "v2", value: new THREE.Vector2( 512, 512 ) }, 21 | "cameraNear": { type: "f", value: 1 }, 22 | "cameraFar": { type: "f", value: 100 }, 23 | "onlyAO": { type: "i", value: 0 }, 24 | "aoClamp": { type: "f", value: 0.5 }, 25 | "lumInfluence": { type: "f", value: 0.5 } 26 | 27 | }, 28 | 29 | vertexShader: [ 30 | 31 | "varying vec2 vUv;", 32 | 33 | "void main() {", 34 | 35 | "vUv = uv;", 36 | 37 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 38 | 39 | "}" 40 | 41 | ].join("\n"), 42 | 43 | fragmentShader: [ 44 | 45 | "uniform float cameraNear;", 46 | "uniform float cameraFar;", 47 | 48 | "uniform bool onlyAO;", // use only ambient occlusion pass? 49 | 50 | "uniform vec2 size;", // texture width, height 51 | "uniform float aoClamp;", // depth clamp - reduces haloing at screen edges 52 | 53 | "uniform float lumInfluence;", // how much luminance affects occlusion 54 | 55 | "uniform sampler2D tDiffuse;", 56 | "uniform sampler2D tDepth;", 57 | 58 | "varying vec2 vUv;", 59 | 60 | // "#define PI 3.14159265", 61 | "#define DL 2.399963229728653", // PI * ( 3.0 - sqrt( 5.0 ) ) 62 | "#define EULER 2.718281828459045", 63 | 64 | // helpers 65 | 66 | "float width = size.x;", // texture width 67 | "float height = size.y;", // texture height 68 | 69 | "float cameraFarPlusNear = cameraFar + cameraNear;", 70 | "float cameraFarMinusNear = cameraFar - cameraNear;", 71 | "float cameraCoef = 2.0 * cameraNear;", 72 | 73 | // user variables 74 | 75 | "const int samples = 8;", // ao sample count 76 | "const float radius = 5.0;", // ao radius 77 | 78 | "const bool useNoise = false;", // use noise instead of pattern for sample dithering 79 | "const float noiseAmount = 0.0003;", // dithering amount 80 | 81 | "const float diffArea = 0.4;", // self-shadowing reduction 82 | "const float gDisplace = 0.4;", // gauss bell center 83 | 84 | 85 | // RGBA depth 86 | 87 | "float unpackDepth( const in vec4 rgba_depth ) {", 88 | 89 | "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 );", 90 | "float depth = dot( rgba_depth, bit_shift );", 91 | "return depth;", 92 | 93 | "}", 94 | 95 | // generating noise / pattern texture for dithering 96 | 97 | "vec2 rand( const vec2 coord ) {", 98 | 99 | "vec2 noise;", 100 | 101 | "if ( useNoise ) {", 102 | 103 | "float nx = dot ( coord, vec2( 12.9898, 78.233 ) );", 104 | "float ny = dot ( coord, vec2( 12.9898, 78.233 ) * 2.0 );", 105 | 106 | "noise = clamp( fract ( 43758.5453 * sin( vec2( nx, ny ) ) ), 0.0, 1.0 );", 107 | 108 | "} else {", 109 | 110 | "float ff = fract( 1.0 - coord.s * ( width / 2.0 ) );", 111 | "float gg = fract( coord.t * ( height / 2.0 ) );", 112 | 113 | "noise = vec2( 0.25, 0.75 ) * vec2( ff ) + vec2( 0.75, 0.25 ) * gg;", 114 | 115 | "}", 116 | 117 | "return ( noise * 2.0 - 1.0 ) * noiseAmount;", 118 | 119 | "}", 120 | 121 | "float readDepth( const in vec2 coord ) {", 122 | 123 | // "return ( 2.0 * cameraNear ) / ( cameraFar + cameraNear - unpackDepth( texture2D( tDepth, coord ) ) * ( cameraFar - cameraNear ) );", 124 | "return cameraCoef / ( cameraFarPlusNear - unpackDepth( texture2D( tDepth, coord ) ) * cameraFarMinusNear );", 125 | 126 | 127 | "}", 128 | 129 | "float compareDepths( const in float depth1, const in float depth2, inout int far ) {", 130 | 131 | "float garea = 2.0;", // gauss bell width 132 | "float diff = ( depth1 - depth2 ) * 100.0;", // depth difference (0-100) 133 | 134 | // reduce left bell width to avoid self-shadowing 135 | 136 | "if ( diff < gDisplace ) {", 137 | 138 | "garea = diffArea;", 139 | 140 | "} else {", 141 | 142 | "far = 1;", 143 | 144 | "}", 145 | 146 | "float dd = diff - gDisplace;", 147 | "float gauss = pow( EULER, -2.0 * dd * dd / ( garea * garea ) );", 148 | "return gauss;", 149 | 150 | "}", 151 | 152 | "float calcAO( float depth, float dw, float dh ) {", 153 | 154 | "float dd = radius - depth * radius;", 155 | "vec2 vv = vec2( dw, dh );", 156 | 157 | "vec2 coord1 = vUv + dd * vv;", 158 | "vec2 coord2 = vUv - dd * vv;", 159 | 160 | "float temp1 = 0.0;", 161 | "float temp2 = 0.0;", 162 | 163 | "int far = 0;", 164 | "temp1 = compareDepths( depth, readDepth( coord1 ), far );", 165 | 166 | // DEPTH EXTRAPOLATION 167 | 168 | "if ( far > 0 ) {", 169 | 170 | "temp2 = compareDepths( readDepth( coord2 ), depth, far );", 171 | "temp1 += ( 1.0 - temp1 ) * temp2;", 172 | 173 | "}", 174 | 175 | "return temp1;", 176 | 177 | "}", 178 | 179 | "void main() {", 180 | 181 | "vec2 noise = rand( vUv );", 182 | "float depth = readDepth( vUv );", 183 | 184 | "float tt = clamp( depth, aoClamp, 1.0 );", 185 | 186 | "float w = ( 1.0 / width ) / tt + ( noise.x * ( 1.0 - noise.x ) );", 187 | "float h = ( 1.0 / height ) / tt + ( noise.y * ( 1.0 - noise.y ) );", 188 | 189 | "float ao = 0.0;", 190 | 191 | "float dz = 1.0 / float( samples );", 192 | "float z = 1.0 - dz / 2.0;", 193 | "float l = 0.0;", 194 | 195 | "for ( int i = 0; i <= samples; i ++ ) {", 196 | 197 | "float r = sqrt( 1.0 - z );", 198 | 199 | "float pw = cos( l ) * r;", 200 | "float ph = sin( l ) * r;", 201 | "ao += calcAO( depth, pw * w, ph * h );", 202 | "z = z - dz;", 203 | "l = l + DL;", 204 | 205 | "}", 206 | 207 | "ao /= float( samples );", 208 | "ao = 1.0 - ao;", 209 | 210 | "vec3 color = texture2D( tDiffuse, vUv ).rgb;", 211 | 212 | "vec3 lumcoeff = vec3( 0.299, 0.587, 0.114 );", 213 | "float lum = dot( color.rgb, lumcoeff );", 214 | "vec3 luminance = vec3( lum );", 215 | 216 | "vec3 final = vec3( color * mix( vec3( ao ), vec3( 1.0 ), luminance * lumInfluence ) );", // mix( color * ao, white, luminance ) 217 | 218 | "if ( onlyAO ) {", 219 | 220 | "final = vec3( mix( vec3( ao ), vec3( 1.0 ), luminance * lumInfluence ) );", // ambient occlusion only 221 | 222 | "}", 223 | 224 | "gl_FragColor = vec4( final, 1.0 );", 225 | 226 | "}" 227 | 228 | ].join("\n") 229 | 230 | }; 231 | -------------------------------------------------------------------------------- /js/libs/shaders/SepiaShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Sepia tone shader 5 | * based on glfx.js sepia shader 6 | * https://github.com/evanw/glfx.js 7 | */ 8 | 9 | THREE.SepiaShader = { 10 | 11 | uniforms: { 12 | 13 | "tDiffuse": { type: "t", value: null }, 14 | "amount": { type: "f", value: 1.0 } 15 | 16 | }, 17 | 18 | vertexShader: [ 19 | 20 | "varying vec2 vUv;", 21 | 22 | "void main() {", 23 | 24 | "vUv = uv;", 25 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 26 | 27 | "}" 28 | 29 | ].join("\n"), 30 | 31 | fragmentShader: [ 32 | 33 | "uniform float amount;", 34 | 35 | "uniform sampler2D tDiffuse;", 36 | 37 | "varying vec2 vUv;", 38 | 39 | "void main() {", 40 | 41 | "vec4 color = texture2D( tDiffuse, vUv );", 42 | "vec3 c = color.rgb;", 43 | 44 | "color.r = dot( c, vec3( 1.0 - 0.607 * amount, 0.769 * amount, 0.189 * amount ) );", 45 | "color.g = dot( c, vec3( 0.349 * amount, 1.0 - 0.314 * amount, 0.168 * amount ) );", 46 | "color.b = dot( c, vec3( 0.272 * amount, 0.534 * amount, 1.0 - 0.869 * amount ) );", 47 | 48 | "gl_FragColor = vec4( min( vec3( 1.0 ), color.rgb ), color.a );", 49 | 50 | "}" 51 | 52 | ].join("\n") 53 | 54 | }; 55 | -------------------------------------------------------------------------------- /js/libs/shaders/TechnicolorShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author flimshaw / http://charliehoey.com 3 | * 4 | * Technicolor Shader 5 | * Simulates the look of the two-strip technicolor process popular in early 20th century films. 6 | * More historical info here: http://www.widescreenmuseum.com/oldcolor/technicolor1.htm 7 | * Demo here: http://charliehoey.com/technicolor_shader/shader_test.html 8 | */ 9 | 10 | THREE.TechnicolorShader = { 11 | 12 | uniforms: { 13 | 14 | "tDiffuse": { type: "t", value: null }, 15 | 16 | }, 17 | 18 | vertexShader: [ 19 | 20 | "varying vec2 vUv;", 21 | 22 | "void main() {", 23 | 24 | "vUv = uv;", 25 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 26 | 27 | "}" 28 | 29 | ].join("\n"), 30 | 31 | fragmentShader: [ 32 | 33 | "uniform sampler2D tDiffuse;", 34 | "varying vec2 vUv;", 35 | 36 | "void main() {", 37 | 38 | "vec4 tex = texture2D( tDiffuse, vec2( vUv.x, vUv.y ) );", 39 | "vec4 newTex = vec4(tex.r, (tex.g + tex.b) * .5, (tex.g + tex.b) * .5, 1.0);", 40 | 41 | "gl_FragColor = newTex;", 42 | 43 | "}" 44 | 45 | ].join("\n") 46 | 47 | }; 48 | -------------------------------------------------------------------------------- /js/libs/shaders/TriangleBlurShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author zz85 / http://www.lab4games.net/zz85/blog 3 | * 4 | * Triangle blur shader 5 | * based on glfx.js triangle blur shader 6 | * https://github.com/evanw/glfx.js 7 | * 8 | * A basic blur filter, which convolves the image with a 9 | * pyramid filter. The pyramid filter is separable and is applied as two 10 | * perpendicular triangle filters. 11 | */ 12 | 13 | THREE.TriangleBlurShader = { 14 | 15 | uniforms : { 16 | 17 | "texture": { type: "t", value: null }, 18 | "delta": { type: "v2", value:new THREE.Vector2( 1, 1 ) } 19 | 20 | }, 21 | 22 | vertexShader: [ 23 | 24 | "varying vec2 vUv;", 25 | 26 | "void main() {", 27 | 28 | "vUv = uv;", 29 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 30 | 31 | "}" 32 | 33 | ].join("\n"), 34 | 35 | fragmentShader: [ 36 | 37 | "#define ITERATIONS 10.0", 38 | 39 | "uniform sampler2D texture;", 40 | "uniform vec2 delta;", 41 | 42 | "varying vec2 vUv;", 43 | 44 | "float random( vec3 scale, float seed ) {", 45 | 46 | // use the fragment position for a different seed per-pixel 47 | 48 | "return fract( sin( dot( gl_FragCoord.xyz + seed, scale ) ) * 43758.5453 + seed );", 49 | 50 | "}", 51 | 52 | "void main() {", 53 | 54 | "vec4 color = vec4( 0.0 );", 55 | 56 | "float total = 0.0;", 57 | 58 | // randomize the lookup values to hide the fixed number of samples 59 | 60 | "float offset = random( vec3( 12.9898, 78.233, 151.7182 ), 0.0 );", 61 | 62 | "for ( float t = -ITERATIONS; t <= ITERATIONS; t ++ ) {", 63 | 64 | "float percent = ( t + offset - 0.5 ) / ITERATIONS;", 65 | "float weight = 1.0 - abs( percent );", 66 | 67 | "color += texture2D( texture, vUv + delta * percent ) * weight;", 68 | "total += weight;", 69 | 70 | "}", 71 | 72 | "gl_FragColor = color / total;", 73 | 74 | "}" 75 | 76 | ].join("\n") 77 | 78 | }; 79 | -------------------------------------------------------------------------------- /js/libs/shaders/UnpackDepthRGBAShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Unpack RGBA depth shader 5 | * - show RGBA encoded depth as monochrome color 6 | */ 7 | 8 | THREE.UnpackDepthRGBAShader = { 9 | 10 | uniforms: { 11 | 12 | "tDiffuse": { type: "t", value: null }, 13 | "opacity": { type: "f", value: 1.0 } 14 | 15 | }, 16 | 17 | vertexShader: [ 18 | 19 | "varying vec2 vUv;", 20 | 21 | "void main() {", 22 | 23 | "vUv = uv;", 24 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 25 | 26 | "}" 27 | 28 | ].join("\n"), 29 | 30 | fragmentShader: [ 31 | 32 | "uniform float opacity;", 33 | 34 | "uniform sampler2D tDiffuse;", 35 | 36 | "varying vec2 vUv;", 37 | 38 | // RGBA depth 39 | 40 | "float unpackDepth( const in vec4 rgba_depth ) {", 41 | 42 | "const vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );", 43 | "float depth = dot( rgba_depth, bit_shift );", 44 | "return depth;", 45 | 46 | "}", 47 | 48 | "void main() {", 49 | 50 | "float depth = 1.0 - unpackDepth( texture2D( tDiffuse, vUv ) );", 51 | "gl_FragColor = opacity * vec4( vec3( depth ), 1.0 );", 52 | 53 | "}" 54 | 55 | ].join("\n") 56 | 57 | }; 58 | -------------------------------------------------------------------------------- /js/libs/shaders/VerticalBlurShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author zz85 / http://www.lab4games.net/zz85/blog 3 | * 4 | * Two pass Gaussian blur filter (horizontal and vertical blur shaders) 5 | * - described in http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/ 6 | * and used in http://www.cake23.de/traveling-wavefronts-lit-up.html 7 | * 8 | * - 9 samples per pass 9 | * - standard deviation 2.7 10 | * - "h" and "v" parameters should be set to "1 / width" and "1 / height" 11 | */ 12 | 13 | THREE.VerticalBlurShader = { 14 | 15 | uniforms: { 16 | 17 | "tDiffuse": { type: "t", value: null }, 18 | "v": { type: "f", value: 1.0 / 512.0 } 19 | 20 | }, 21 | 22 | vertexShader: [ 23 | 24 | "varying vec2 vUv;", 25 | 26 | "void main() {", 27 | 28 | "vUv = uv;", 29 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 30 | 31 | "}" 32 | 33 | ].join("\n"), 34 | 35 | fragmentShader: [ 36 | 37 | "uniform sampler2D tDiffuse;", 38 | "uniform float v;", 39 | 40 | "varying vec2 vUv;", 41 | 42 | "void main() {", 43 | 44 | "vec4 sum = vec4( 0.0 );", 45 | 46 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * v ) ) * 0.051;", 47 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * v ) ) * 0.0918;", 48 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * v ) ) * 0.12245;", 49 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * v ) ) * 0.1531;", 50 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", 51 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * v ) ) * 0.1531;", 52 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * v ) ) * 0.12245;", 53 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * v ) ) * 0.0918;", 54 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * v ) ) * 0.051;", 55 | 56 | "gl_FragColor = sum;", 57 | 58 | "}" 59 | 60 | ].join("\n") 61 | 62 | }; 63 | -------------------------------------------------------------------------------- /js/libs/shaders/VerticalTiltShiftShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Simple fake tilt-shift effect, modulating two pass Gaussian blur (see above) by vertical position 5 | * 6 | * - 9 samples per pass 7 | * - standard deviation 2.7 8 | * - "h" and "v" parameters should be set to "1 / width" and "1 / height" 9 | * - "r" parameter control where "focused" horizontal line lies 10 | */ 11 | 12 | THREE.VerticalTiltShiftShader = { 13 | 14 | uniforms: { 15 | 16 | "tDiffuse": { type: "t", value: null }, 17 | "v": { type: "f", value: 1.0 / 512.0 }, 18 | "r": { type: "f", value: 0.35 } 19 | 20 | }, 21 | 22 | vertexShader: [ 23 | 24 | "varying vec2 vUv;", 25 | 26 | "void main() {", 27 | 28 | "vUv = uv;", 29 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 30 | 31 | "}" 32 | 33 | ].join("\n"), 34 | 35 | fragmentShader: [ 36 | 37 | "uniform sampler2D tDiffuse;", 38 | "uniform float v;", 39 | "uniform float r;", 40 | 41 | "varying vec2 vUv;", 42 | 43 | "void main() {", 44 | 45 | "vec4 sum = vec4( 0.0 );", 46 | 47 | "float vv = v * abs( r - vUv.y );", 48 | 49 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * vv ) ) * 0.051;", 50 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * vv ) ) * 0.0918;", 51 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * vv ) ) * 0.12245;", 52 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * vv ) ) * 0.1531;", 53 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", 54 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * vv ) ) * 0.1531;", 55 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * vv ) ) * 0.12245;", 56 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * vv ) ) * 0.0918;", 57 | "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * vv ) ) * 0.051;", 58 | 59 | "gl_FragColor = sum;", 60 | 61 | "}" 62 | 63 | ].join("\n") 64 | 65 | }; 66 | -------------------------------------------------------------------------------- /js/libs/shaders/VignetteShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Vignette shader 5 | * based on PaintEffect postprocess from ro.me 6 | * http://code.google.com/p/3-dreams-of-black/source/browse/deploy/js/effects/PaintEffect.js 7 | */ 8 | 9 | THREE.VignetteShader = { 10 | 11 | uniforms: { 12 | 13 | "tDiffuse": { type: "t", value: null }, 14 | "offset": { type: "f", value: 1.0 }, 15 | "darkness": { type: "f", value: 1.0 } 16 | 17 | }, 18 | 19 | vertexShader: [ 20 | 21 | "varying vec2 vUv;", 22 | 23 | "void main() {", 24 | 25 | "vUv = uv;", 26 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 27 | 28 | "}" 29 | 30 | ].join("\n"), 31 | 32 | fragmentShader: [ 33 | 34 | "uniform float offset;", 35 | "uniform float darkness;", 36 | 37 | "uniform sampler2D tDiffuse;", 38 | 39 | "varying vec2 vUv;", 40 | 41 | "void main() {", 42 | 43 | // Eskil's vignette 44 | 45 | "vec4 texel = texture2D( tDiffuse, vUv );", 46 | "vec2 uv = ( vUv - vec2( 0.5 ) ) * vec2( offset );", 47 | "gl_FragColor = vec4( mix( texel.rgb, vec3( 1.0 - darkness ), dot( uv, uv ) ), texel.a );", 48 | 49 | /* 50 | // alternative version from glfx.js 51 | // this one makes more "dusty" look (as opposed to "burned") 52 | 53 | "vec4 color = texture2D( tDiffuse, vUv );", 54 | "float dist = distance( vUv, vec2( 0.5 ) );", 55 | "color.rgb *= smoothstep( 0.8, offset * 0.799, dist *( darkness + offset ) );", 56 | "gl_FragColor = color;", 57 | */ 58 | 59 | "}" 60 | 61 | ].join("\n") 62 | 63 | }; 64 | --------------------------------------------------------------------------------