├── README.md └── glow-shader ├── .idea ├── earthThree.iml ├── modules.xml └── workspace.xml ├── bg1.png ├── bg2.png ├── build ├── TrackballControls.js └── three.js └── glow.html /README.md: -------------------------------------------------------------------------------- 1 | # ThreeJSGlow-Atmosphere 2 | show the glow and atmosphere by threejs 3 | effort: 4 | ![image](https://github.com/StringKun/ThreeJSGlow-Atmosphere/blob/master/glow-shader/bg1.png) 5 | ![image](https://github.com/StringKun/ThreeJSGlow-Atmosphere/blob/master/glow-shader/bg2.png) 6 | -------------------------------------------------------------------------------- /glow-shader/.idea/earthThree.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /glow-shader/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /glow-shader/.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | PlaneBufferGeometry 38 | coeficient 39 | PlaneGeometry 40 | depthWrite 41 | renderOrder 42 | controls 43 | depth 44 | mesh 45 | material_glow 46 | material 47 | exchangeShader 48 | 49 | 50 | 51 | 56 | 57 | 58 | 59 | 60 | true 61 | DEFINITION_ORDER 62 | 63 | 64 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 92 | 93 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | project 152 | 153 | 154 | true 155 | 156 | 157 | 158 | DIRECTORY 159 | 160 | false 161 | 162 | 163 | 164 | 165 | 167 | 168 | 169 | 170 | 1509007569147 171 | 178 | 179 | 180 | 181 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 208 | 209 | 211 | 212 | 213 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | -------------------------------------------------------------------------------- /glow-shader/bg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringKun/ThreeJSGlow-Atmosphere/6901d970a04ffe9ba3ea0a8d9e71ade5d53f2514/glow-shader/bg1.png -------------------------------------------------------------------------------- /glow-shader/bg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringKun/ThreeJSGlow-Atmosphere/6901d970a04ffe9ba3ea0a8d9e71ade5d53f2514/glow-shader/bg2.png -------------------------------------------------------------------------------- /glow-shader/build/TrackballControls.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Eberhard Graether / http://egraether.com/ 3 | * @author Mark Lundin / http://mark-lundin.com 4 | * @author Simone Manini / http://daron1337.github.io 5 | * @author Luca Antiga / http://lantiga.github.io 6 | */ 7 | 8 | THREE.TrackballControls = function ( object, domElement ) { 9 | 10 | var _this = this; 11 | var STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 }; 12 | 13 | this.object = object; 14 | this.domElement = ( domElement !== undefined ) ? domElement : document; 15 | 16 | // API 17 | 18 | this.enabled = true; 19 | 20 | this.screen = { left: 0, top: 0, width: 0, height: 0 }; 21 | 22 | this.rotateSpeed = 1.0; 23 | this.zoomSpeed = 1.2; 24 | this.panSpeed = 0.3; 25 | 26 | this.noRotate = false; 27 | this.noZoom = false; 28 | this.noPan = false; 29 | 30 | this.staticMoving = false; 31 | this.dynamicDampingFactor = 0.2; 32 | 33 | this.minDistance = 0; 34 | this.maxDistance = Infinity; 35 | 36 | this.keys = [ 65 /*A*/, 83 /*S*/, 68 /*D*/ ]; 37 | 38 | // internals 39 | 40 | this.target = new THREE.Vector3(); 41 | 42 | var EPS = 0.000001; 43 | 44 | var lastPosition = new THREE.Vector3(); 45 | 46 | var _state = STATE.NONE, 47 | _prevState = STATE.NONE, 48 | 49 | _eye = new THREE.Vector3(), 50 | 51 | _movePrev = new THREE.Vector2(), 52 | _moveCurr = new THREE.Vector2(), 53 | 54 | _lastAxis = new THREE.Vector3(), 55 | _lastAngle = 0, 56 | 57 | _zoomStart = new THREE.Vector2(), 58 | _zoomEnd = new THREE.Vector2(), 59 | 60 | _touchZoomDistanceStart = 0, 61 | _touchZoomDistanceEnd = 0, 62 | 63 | _panStart = new THREE.Vector2(), 64 | _panEnd = new THREE.Vector2(); 65 | 66 | // for reset 67 | 68 | this.target0 = this.target.clone(); 69 | this.position0 = this.object.position.clone(); 70 | this.up0 = this.object.up.clone(); 71 | 72 | // events 73 | 74 | var changeEvent = { type: 'change' }; 75 | var startEvent = { type: 'start' }; 76 | var endEvent = { type: 'end' }; 77 | 78 | 79 | // methods 80 | 81 | this.handleResize = function () { 82 | 83 | if ( this.domElement === document ) { 84 | 85 | this.screen.left = 0; 86 | this.screen.top = 0; 87 | this.screen.width = window.innerWidth; 88 | this.screen.height = window.innerHeight; 89 | 90 | } else { 91 | 92 | var box = this.domElement.getBoundingClientRect(); 93 | // adjustments come from similar code in the jquery offset() function 94 | var d = this.domElement.ownerDocument.documentElement; 95 | this.screen.left = box.left + window.pageXOffset - d.clientLeft; 96 | this.screen.top = box.top + window.pageYOffset - d.clientTop; 97 | this.screen.width = box.width; 98 | this.screen.height = box.height; 99 | 100 | } 101 | 102 | }; 103 | 104 | this.handleEvent = function ( event ) { 105 | 106 | if ( typeof this[ event.type ] == 'function' ) { 107 | 108 | this[ event.type ]( event ); 109 | 110 | } 111 | 112 | }; 113 | 114 | var getMouseOnScreen = ( function () { 115 | 116 | var vector = new THREE.Vector2(); 117 | 118 | return function getMouseOnScreen( pageX, pageY ) { 119 | 120 | vector.set( 121 | ( pageX - _this.screen.left ) / _this.screen.width, 122 | ( pageY - _this.screen.top ) / _this.screen.height 123 | ); 124 | 125 | return vector; 126 | 127 | }; 128 | 129 | }() ); 130 | 131 | var getMouseOnCircle = ( function () { 132 | 133 | var vector = new THREE.Vector2(); 134 | 135 | return function getMouseOnCircle( pageX, pageY ) { 136 | 137 | vector.set( 138 | ( ( pageX - _this.screen.width * 0.5 - _this.screen.left ) / ( _this.screen.width * 0.5 ) ), 139 | ( ( _this.screen.height + 2 * ( _this.screen.top - pageY ) ) / _this.screen.width ) // screen.width intentional 140 | ); 141 | 142 | return vector; 143 | 144 | }; 145 | 146 | }() ); 147 | 148 | this.rotateCamera = ( function() { 149 | 150 | var axis = new THREE.Vector3(), 151 | quaternion = new THREE.Quaternion(), 152 | eyeDirection = new THREE.Vector3(), 153 | objectUpDirection = new THREE.Vector3(), 154 | objectSidewaysDirection = new THREE.Vector3(), 155 | moveDirection = new THREE.Vector3(), 156 | angle; 157 | 158 | return function rotateCamera() { 159 | 160 | moveDirection.set( _moveCurr.x - _movePrev.x, _moveCurr.y - _movePrev.y, 0 ); 161 | angle = moveDirection.length(); 162 | 163 | if ( angle ) { 164 | 165 | _eye.copy( _this.object.position ).sub( _this.target ); 166 | 167 | eyeDirection.copy( _eye ).normalize(); 168 | objectUpDirection.copy( _this.object.up ).normalize(); 169 | objectSidewaysDirection.crossVectors( objectUpDirection, eyeDirection ).normalize(); 170 | 171 | objectUpDirection.setLength( _moveCurr.y - _movePrev.y ); 172 | objectSidewaysDirection.setLength( _moveCurr.x - _movePrev.x ); 173 | 174 | moveDirection.copy( objectUpDirection.add( objectSidewaysDirection ) ); 175 | 176 | axis.crossVectors( moveDirection, _eye ).normalize(); 177 | 178 | angle *= _this.rotateSpeed; 179 | quaternion.setFromAxisAngle( axis, angle ); 180 | 181 | _eye.applyQuaternion( quaternion ); 182 | _this.object.up = new THREE.Vector3(0,1,0); 183 | 184 | _lastAxis.copy( axis ); 185 | _lastAngle = angle; 186 | 187 | } else if ( ! _this.staticMoving && _lastAngle ) { 188 | 189 | _lastAngle *= Math.sqrt( 1.0 - _this.dynamicDampingFactor ); 190 | _eye.copy( _this.object.position ).sub( _this.target ); 191 | quaternion.setFromAxisAngle( _lastAxis, _lastAngle ); 192 | _eye.applyQuaternion( quaternion ); 193 | // _this.object.up.applyQuaternion( quaternion ); 194 | _this.object.up = new THREE.Vector3(0,1,0); 195 | 196 | } 197 | 198 | _movePrev.copy( _moveCurr ); 199 | 200 | }; 201 | 202 | }() ); 203 | 204 | 205 | this.zoomCamera = function () { 206 | 207 | var factor; 208 | 209 | if ( _state === STATE.TOUCH_ZOOM_PAN ) { 210 | 211 | factor = _touchZoomDistanceStart / _touchZoomDistanceEnd; 212 | _touchZoomDistanceStart = _touchZoomDistanceEnd; 213 | _eye.multiplyScalar( factor ); 214 | 215 | } else { 216 | 217 | factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * _this.zoomSpeed; 218 | 219 | if ( factor !== 1.0 && factor > 0.0 ) { 220 | 221 | _eye.multiplyScalar( factor ); 222 | 223 | } 224 | 225 | if ( _this.staticMoving ) { 226 | 227 | _zoomStart.copy( _zoomEnd ); 228 | 229 | } else { 230 | 231 | _zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor; 232 | 233 | } 234 | 235 | } 236 | 237 | }; 238 | 239 | this.panCamera = ( function() { 240 | 241 | var mouseChange = new THREE.Vector2(), 242 | objectUp = new THREE.Vector3(), 243 | pan = new THREE.Vector3(); 244 | 245 | return function panCamera() { 246 | 247 | mouseChange.copy( _panEnd ).sub( _panStart ); 248 | 249 | if ( mouseChange.lengthSq() ) { 250 | 251 | mouseChange.multiplyScalar( _eye.length() * _this.panSpeed ); 252 | 253 | pan.copy( _eye ).cross( _this.object.up ).setLength( mouseChange.x ); 254 | pan.add( objectUp.copy( _this.object.up ).setLength( mouseChange.y ) ); 255 | 256 | _this.object.position.add( pan ); 257 | _this.target.add( pan ); 258 | 259 | if ( _this.staticMoving ) { 260 | 261 | _panStart.copy( _panEnd ); 262 | 263 | } else { 264 | 265 | _panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( _this.dynamicDampingFactor ) ); 266 | 267 | } 268 | 269 | } 270 | 271 | }; 272 | 273 | }() ); 274 | 275 | this.checkDistances = function () { 276 | 277 | if ( ! _this.noZoom || ! _this.noPan ) { 278 | 279 | if ( _eye.lengthSq() > _this.maxDistance * _this.maxDistance ) { 280 | 281 | _this.object.position.addVectors( _this.target, _eye.setLength( _this.maxDistance ) ); 282 | _zoomStart.copy( _zoomEnd ); 283 | 284 | } 285 | 286 | if ( _eye.lengthSq() < _this.minDistance * _this.minDistance ) { 287 | 288 | _this.object.position.addVectors( _this.target, _eye.setLength( _this.minDistance ) ); 289 | _zoomStart.copy( _zoomEnd ); 290 | 291 | } 292 | 293 | } 294 | 295 | }; 296 | 297 | this.update = function () { 298 | 299 | _eye.subVectors( _this.object.position, _this.target ); 300 | 301 | if ( ! _this.noRotate ) { 302 | 303 | _this.rotateCamera(); 304 | 305 | } 306 | 307 | if ( ! _this.noZoom ) { 308 | 309 | _this.zoomCamera(); 310 | 311 | } 312 | 313 | if ( ! _this.noPan ) { 314 | 315 | _this.panCamera(); 316 | 317 | } 318 | 319 | _this.object.position.addVectors( _this.target, _eye ); 320 | 321 | _this.checkDistances(); 322 | 323 | _this.object.lookAt( _this.target ); 324 | 325 | if ( lastPosition.distanceToSquared( _this.object.position ) > EPS ) { 326 | 327 | _this.dispatchEvent( changeEvent ); 328 | 329 | lastPosition.copy( _this.object.position ); 330 | 331 | } 332 | 333 | }; 334 | 335 | this.reset = function () { 336 | 337 | _state = STATE.NONE; 338 | _prevState = STATE.NONE; 339 | 340 | _this.target.copy( _this.target0 ); 341 | _this.object.position.copy( _this.position0 ); 342 | _this.object.up.copy( _this.up0 ); 343 | 344 | _eye.subVectors( _this.object.position, _this.target ); 345 | 346 | _this.object.lookAt( _this.target ); 347 | 348 | _this.dispatchEvent( changeEvent ); 349 | 350 | lastPosition.copy( _this.object.position ); 351 | 352 | }; 353 | 354 | // listeners 355 | 356 | function keydown( event ) { 357 | 358 | if ( _this.enabled === false ) return; 359 | 360 | window.removeEventListener( 'keydown', keydown ); 361 | 362 | _prevState = _state; 363 | 364 | if ( _state !== STATE.NONE ) { 365 | 366 | return; 367 | 368 | } else if ( event.keyCode === _this.keys[ STATE.ROTATE ] && ! _this.noRotate ) { 369 | 370 | _state = STATE.ROTATE; 371 | 372 | } else if ( event.keyCode === _this.keys[ STATE.ZOOM ] && ! _this.noZoom ) { 373 | 374 | _state = STATE.ZOOM; 375 | 376 | } else if ( event.keyCode === _this.keys[ STATE.PAN ] && ! _this.noPan ) { 377 | 378 | _state = STATE.PAN; 379 | 380 | } 381 | 382 | } 383 | 384 | function keyup( event ) { 385 | 386 | if ( _this.enabled === false ) return; 387 | 388 | _state = _prevState; 389 | 390 | window.addEventListener( 'keydown', keydown, false ); 391 | 392 | } 393 | 394 | function mousedown( event ) { 395 | 396 | if ( _this.enabled === false ) return; 397 | 398 | event.preventDefault(); 399 | event.stopPropagation(); 400 | 401 | if ( _state === STATE.NONE ) { 402 | 403 | _state = event.button; 404 | 405 | } 406 | 407 | if ( _state === STATE.ROTATE && ! _this.noRotate ) { 408 | 409 | _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) ); 410 | _movePrev.copy( _moveCurr ); 411 | 412 | } else if ( _state === STATE.ZOOM && ! _this.noZoom ) { 413 | 414 | _zoomStart.copy( getMouseOnScreen( event.pageX, event.pageY ) ); 415 | _zoomEnd.copy( _zoomStart ); 416 | 417 | } else if ( _state === STATE.PAN && ! _this.noPan ) { 418 | 419 | _panStart.copy( getMouseOnScreen( event.pageX, event.pageY ) ); 420 | _panEnd.copy( _panStart ); 421 | 422 | } 423 | 424 | document.addEventListener( 'mousemove', mousemove, false ); 425 | document.addEventListener( 'mouseup', mouseup, false ); 426 | 427 | _this.dispatchEvent( startEvent ); 428 | 429 | } 430 | 431 | function mousemove( event ) { 432 | 433 | if ( _this.enabled === false ) return; 434 | 435 | event.preventDefault(); 436 | event.stopPropagation(); 437 | 438 | if ( _state === STATE.ROTATE && ! _this.noRotate ) { 439 | 440 | _movePrev.copy( _moveCurr ); 441 | _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) ); 442 | 443 | } else if ( _state === STATE.ZOOM && ! _this.noZoom ) { 444 | 445 | _zoomEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) ); 446 | 447 | } else if ( _state === STATE.PAN && ! _this.noPan ) { 448 | 449 | _panEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) ); 450 | 451 | } 452 | 453 | } 454 | 455 | function mouseup( event ) { 456 | 457 | if ( _this.enabled === false ) return; 458 | 459 | event.preventDefault(); 460 | event.stopPropagation(); 461 | 462 | _state = STATE.NONE; 463 | 464 | document.removeEventListener( 'mousemove', mousemove ); 465 | document.removeEventListener( 'mouseup', mouseup ); 466 | _this.dispatchEvent( endEvent ); 467 | 468 | } 469 | 470 | function mousewheel( event ) { 471 | 472 | if ( _this.enabled === false ) return; 473 | 474 | event.preventDefault(); 475 | event.stopPropagation(); 476 | 477 | switch ( event.deltaMode ) { 478 | 479 | case 2: 480 | // Zoom in pages 481 | _zoomStart.y -= event.deltaY * 0.025; 482 | break; 483 | 484 | case 1: 485 | // Zoom in lines 486 | _zoomStart.y -= event.deltaY * 0.01; 487 | break; 488 | 489 | default: 490 | // undefined, 0, assume pixels 491 | _zoomStart.y -= event.deltaY * 0.00025; 492 | break; 493 | 494 | } 495 | 496 | _this.dispatchEvent( startEvent ); 497 | _this.dispatchEvent( endEvent ); 498 | 499 | } 500 | 501 | function touchstart( event ) { 502 | 503 | if ( _this.enabled === false ) return; 504 | 505 | switch ( event.touches.length ) { 506 | 507 | case 1: 508 | _state = STATE.TOUCH_ROTATE; 509 | _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); 510 | _movePrev.copy( _moveCurr ); 511 | break; 512 | 513 | default: // 2 or more 514 | _state = STATE.TOUCH_ZOOM_PAN; 515 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; 516 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; 517 | _touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy ); 518 | 519 | var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2; 520 | var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2; 521 | _panStart.copy( getMouseOnScreen( x, y ) ); 522 | _panEnd.copy( _panStart ); 523 | break; 524 | 525 | } 526 | 527 | _this.dispatchEvent( startEvent ); 528 | 529 | } 530 | 531 | function touchmove( event ) { 532 | 533 | if ( _this.enabled === false ) return; 534 | 535 | event.preventDefault(); 536 | event.stopPropagation(); 537 | 538 | switch ( event.touches.length ) { 539 | 540 | case 1: 541 | _movePrev.copy( _moveCurr ); 542 | _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); 543 | break; 544 | 545 | default: // 2 or more 546 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; 547 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; 548 | _touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy ); 549 | 550 | var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2; 551 | var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2; 552 | _panEnd.copy( getMouseOnScreen( x, y ) ); 553 | break; 554 | 555 | } 556 | 557 | } 558 | 559 | function touchend( event ) { 560 | 561 | if ( _this.enabled === false ) return; 562 | 563 | switch ( event.touches.length ) { 564 | 565 | case 0: 566 | _state = STATE.NONE; 567 | break; 568 | 569 | case 1: 570 | _state = STATE.TOUCH_ROTATE; 571 | _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); 572 | _movePrev.copy( _moveCurr ); 573 | break; 574 | 575 | } 576 | 577 | _this.dispatchEvent( endEvent ); 578 | 579 | } 580 | 581 | function contextmenu( event ) { 582 | 583 | event.preventDefault(); 584 | 585 | } 586 | 587 | this.dispose = function() { 588 | 589 | this.domElement.removeEventListener( 'contextmenu', contextmenu, false ); 590 | this.domElement.removeEventListener( 'mousedown', mousedown, false ); 591 | this.domElement.removeEventListener( 'wheel', mousewheel, false ); 592 | 593 | this.domElement.removeEventListener( 'touchstart', touchstart, false ); 594 | this.domElement.removeEventListener( 'touchend', touchend, false ); 595 | this.domElement.removeEventListener( 'touchmove', touchmove, false ); 596 | 597 | document.removeEventListener( 'mousemove', mousemove, false ); 598 | document.removeEventListener( 'mouseup', mouseup, false ); 599 | 600 | window.removeEventListener( 'keydown', keydown, false ); 601 | window.removeEventListener( 'keyup', keyup, false ); 602 | 603 | }; 604 | 605 | this.domElement.addEventListener( 'contextmenu', contextmenu, false ); 606 | this.domElement.addEventListener( 'mousedown', mousedown, false ); 607 | this.domElement.addEventListener( 'wheel', mousewheel, false ); 608 | 609 | this.domElement.addEventListener( 'touchstart', touchstart, false ); 610 | this.domElement.addEventListener( 'touchend', touchend, false ); 611 | this.domElement.addEventListener( 'touchmove', touchmove, false ); 612 | 613 | window.addEventListener( 'keydown', keydown, false ); 614 | window.addEventListener( 'keyup', keyup, false ); 615 | 616 | this.handleResize(); 617 | 618 | // force an update at start 619 | this.update(); 620 | 621 | }; 622 | 623 | THREE.TrackballControls.prototype = Object.create( THREE.EventDispatcher.prototype ); 624 | THREE.TrackballControls.prototype.constructor = THREE.TrackballControls; 625 | -------------------------------------------------------------------------------- /glow-shader/glow.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 242 | 243 | 244 | 245 | --------------------------------------------------------------------------------