├── add-some-colour-movement.html
├── add-some-colour-movement.jpg
├── creating-custom-shader.html
├── creating-custom-shader.jpg
├── creating-scene-mesh-camera.html
├── creating-scene-mesh-camera.jpg
├── explosion.png
├── js
├── OrbitControls.js
└── three.min.js
├── lets-make-some-noise.html
├── lets-make-some-noise.jpg
└── modifying-point-over-normal.jpg
/add-some-colour-movement.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Perlin noise | Fireball explosion
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
225 |
226 |
244 |
245 |
325 |
326 |
327 |
--------------------------------------------------------------------------------
/add-some-colour-movement.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spite/vertex-displacement-noise-3d-webgl-glsl-three-js/3ee8c6eb34eb1d4a8a3ccf5743c358c1c8c1b58c/add-some-colour-movement.jpg
--------------------------------------------------------------------------------
/creating-custom-shader.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Perlin noise | Fireball explosion
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
26 |
27 |
36 |
37 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/creating-custom-shader.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spite/vertex-displacement-noise-3d-webgl-glsl-three-js/3ee8c6eb34eb1d4a8a3ccf5743c358c1c8c1b58c/creating-custom-shader.jpg
--------------------------------------------------------------------------------
/creating-scene-mesh-camera.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Perlin noise | Fireball explosion
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
23 |
24 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/creating-scene-mesh-camera.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spite/vertex-displacement-noise-3d-webgl-glsl-three-js/3ee8c6eb34eb1d4a8a3ccf5743c358c1c8c1b58c/creating-scene-mesh-camera.jpg
--------------------------------------------------------------------------------
/explosion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spite/vertex-displacement-noise-3d-webgl-glsl-three-js/3ee8c6eb34eb1d4a8a3ccf5743c358c1c8c1b58c/explosion.png
--------------------------------------------------------------------------------
/js/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 |
9 | // This set of controls performs orbiting, dollying (zooming), and panning.
10 | // Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default).
11 | //
12 | // Orbit - left mouse / touch: one finger move
13 | // Zoom - middle mouse, or mousewheel / touch: two finger spread or squish
14 | // Pan - right mouse, or arrow keys / touch: three finger swipe
15 |
16 | THREE.OrbitControls = function ( object, domElement ) {
17 |
18 | this.object = object;
19 |
20 | this.domElement = ( domElement !== undefined ) ? domElement : document;
21 |
22 | // Set to false to disable this control
23 | this.enabled = true;
24 |
25 | // "target" sets the location of focus, where the object orbits around
26 | this.target = new THREE.Vector3();
27 |
28 | // How far you can dolly in and out ( PerspectiveCamera only )
29 | this.minDistance = 0;
30 | this.maxDistance = Infinity;
31 |
32 | // How far you can zoom in and out ( OrthographicCamera only )
33 | this.minZoom = 0;
34 | this.maxZoom = Infinity;
35 |
36 | // How far you can orbit vertically, upper and lower limits.
37 | // Range is 0 to Math.PI radians.
38 | this.minPolarAngle = 0; // radians
39 | this.maxPolarAngle = Math.PI; // radians
40 |
41 | // How far you can orbit horizontally, upper and lower limits.
42 | // If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].
43 | this.minAzimuthAngle = - Infinity; // radians
44 | this.maxAzimuthAngle = Infinity; // radians
45 |
46 | // Set to true to enable damping (inertia)
47 | // If damping is enabled, you must call controls.update() in your animation loop
48 | this.enableDamping = false;
49 | this.dampingFactor = 0.25;
50 |
51 | // This option actually enables dollying in and out; left as "zoom" for backwards compatibility.
52 | // Set to false to disable zooming
53 | this.enableZoom = true;
54 | this.zoomSpeed = 1.0;
55 |
56 | // Set to false to disable rotating
57 | this.enableRotate = true;
58 | this.rotateSpeed = 1.0;
59 |
60 | // Set to false to disable panning
61 | this.enablePan = true;
62 | this.keyPanSpeed = 7.0; // pixels moved per arrow key push
63 |
64 | // Set to true to automatically rotate around the target
65 | // If auto-rotate is enabled, you must call controls.update() in your animation loop
66 | this.autoRotate = false;
67 | this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
68 |
69 | // Set to false to disable use of the keys
70 | this.enableKeys = true;
71 |
72 | // The four arrow keys
73 | this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };
74 |
75 | // Mouse buttons
76 | this.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };
77 |
78 | // for reset
79 | this.target0 = this.target.clone();
80 | this.position0 = this.object.position.clone();
81 | this.zoom0 = this.object.zoom;
82 |
83 | //
84 | // public methods
85 | //
86 |
87 | this.getPolarAngle = function () {
88 |
89 | return spherical.phi;
90 |
91 | };
92 |
93 | this.getAzimuthalAngle = function () {
94 |
95 | return spherical.theta;
96 |
97 | };
98 |
99 | this.reset = function () {
100 |
101 | scope.target.copy( scope.target0 );
102 | scope.object.position.copy( scope.position0 );
103 | scope.object.zoom = scope.zoom0;
104 |
105 | scope.object.updateProjectionMatrix();
106 | scope.dispatchEvent( changeEvent );
107 |
108 | scope.update();
109 |
110 | state = STATE.NONE;
111 |
112 | };
113 |
114 | // this method is exposed, but perhaps it would be better if we can make it private...
115 | this.update = function () {
116 |
117 | var offset = new THREE.Vector3();
118 |
119 | // so camera.up is the orbit axis
120 | var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );
121 | var quatInverse = quat.clone().inverse();
122 |
123 | var lastPosition = new THREE.Vector3();
124 | var lastQuaternion = new THREE.Quaternion();
125 |
126 | return function update() {
127 |
128 | var position = scope.object.position;
129 |
130 | offset.copy( position ).sub( scope.target );
131 |
132 | // rotate offset to "y-axis-is-up" space
133 | offset.applyQuaternion( quat );
134 |
135 | // angle from z-axis around y-axis
136 | spherical.setFromVector3( offset );
137 |
138 | if ( scope.autoRotate && state === STATE.NONE ) {
139 |
140 | rotateLeft( getAutoRotationAngle() );
141 |
142 | }
143 |
144 | spherical.theta += sphericalDelta.theta;
145 | spherical.phi += sphericalDelta.phi;
146 |
147 | // restrict theta to be between desired limits
148 | spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );
149 |
150 | // restrict phi to be between desired limits
151 | spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );
152 |
153 | spherical.makeSafe();
154 |
155 |
156 | spherical.radius *= scale;
157 |
158 | // restrict radius to be between desired limits
159 | spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );
160 |
161 | // move target to panned location
162 | scope.target.add( panOffset );
163 |
164 | offset.setFromSpherical( spherical );
165 |
166 | // rotate offset back to "camera-up-vector-is-up" space
167 | offset.applyQuaternion( quatInverse );
168 |
169 | position.copy( scope.target ).add( offset );
170 |
171 | scope.object.lookAt( scope.target );
172 |
173 | if ( scope.enableDamping === true ) {
174 |
175 | sphericalDelta.theta *= ( 1 - scope.dampingFactor );
176 | sphericalDelta.phi *= ( 1 - scope.dampingFactor );
177 |
178 | } else {
179 |
180 | sphericalDelta.set( 0, 0, 0 );
181 |
182 | }
183 |
184 | scale = 1;
185 | panOffset.set( 0, 0, 0 );
186 |
187 | // update condition is:
188 | // min(camera displacement, camera rotation in radians)^2 > EPS
189 | // using small-angle approximation cos(x/2) = 1 - x^2 / 8
190 |
191 | if ( zoomChanged ||
192 | lastPosition.distanceToSquared( scope.object.position ) > EPS ||
193 | 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {
194 |
195 | scope.dispatchEvent( changeEvent );
196 |
197 | lastPosition.copy( scope.object.position );
198 | lastQuaternion.copy( scope.object.quaternion );
199 | zoomChanged = false;
200 |
201 | return true;
202 |
203 | }
204 |
205 | return false;
206 |
207 | };
208 |
209 | }();
210 |
211 | this.dispose = function () {
212 |
213 | scope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );
214 | scope.domElement.removeEventListener( 'mousedown', onMouseDown, false );
215 | scope.domElement.removeEventListener( 'wheel', onMouseWheel, false );
216 |
217 | scope.domElement.removeEventListener( 'touchstart', onTouchStart, false );
218 | scope.domElement.removeEventListener( 'touchend', onTouchEnd, false );
219 | scope.domElement.removeEventListener( 'touchmove', onTouchMove, false );
220 |
221 | document.removeEventListener( 'mousemove', onMouseMove, false );
222 | document.removeEventListener( 'mouseup', onMouseUp, false );
223 |
224 | window.removeEventListener( 'keydown', onKeyDown, false );
225 |
226 | //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?
227 |
228 | };
229 |
230 | //
231 | // internals
232 | //
233 |
234 | var scope = this;
235 |
236 | var changeEvent = { type: 'change' };
237 | var startEvent = { type: 'start' };
238 | var endEvent = { type: 'end' };
239 |
240 | var STATE = { NONE: - 1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY: 4, TOUCH_PAN: 5 };
241 |
242 | var state = STATE.NONE;
243 |
244 | var EPS = 0.000001;
245 |
246 | // current position in spherical coordinates
247 | var spherical = new THREE.Spherical();
248 | var sphericalDelta = new THREE.Spherical();
249 |
250 | var scale = 1;
251 | var panOffset = new THREE.Vector3();
252 | var zoomChanged = false;
253 |
254 | var rotateStart = new THREE.Vector2();
255 | var rotateEnd = new THREE.Vector2();
256 | var rotateDelta = new THREE.Vector2();
257 |
258 | var panStart = new THREE.Vector2();
259 | var panEnd = new THREE.Vector2();
260 | var panDelta = new THREE.Vector2();
261 |
262 | var dollyStart = new THREE.Vector2();
263 | var dollyEnd = new THREE.Vector2();
264 | var dollyDelta = new THREE.Vector2();
265 |
266 | function getAutoRotationAngle() {
267 |
268 | return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
269 |
270 | }
271 |
272 | function getZoomScale() {
273 |
274 | return Math.pow( 0.95, scope.zoomSpeed );
275 |
276 | }
277 |
278 | function rotateLeft( angle ) {
279 |
280 | sphericalDelta.theta -= angle;
281 |
282 | }
283 |
284 | function rotateUp( angle ) {
285 |
286 | sphericalDelta.phi -= angle;
287 |
288 | }
289 |
290 | var panLeft = function () {
291 |
292 | var v = new THREE.Vector3();
293 |
294 | return function panLeft( distance, objectMatrix ) {
295 |
296 | v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
297 | v.multiplyScalar( - distance );
298 |
299 | panOffset.add( v );
300 |
301 | };
302 |
303 | }();
304 |
305 | var panUp = function () {
306 |
307 | var v = new THREE.Vector3();
308 |
309 | return function panUp( distance, objectMatrix ) {
310 |
311 | v.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix
312 | v.multiplyScalar( distance );
313 |
314 | panOffset.add( v );
315 |
316 | };
317 |
318 | }();
319 |
320 | // deltaX and deltaY are in pixels; right and down are positive
321 | var pan = function () {
322 |
323 | var offset = new THREE.Vector3();
324 |
325 | return function pan( deltaX, deltaY ) {
326 |
327 | var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
328 |
329 | if ( scope.object instanceof THREE.PerspectiveCamera ) {
330 |
331 | // perspective
332 | var position = scope.object.position;
333 | offset.copy( position ).sub( scope.target );
334 | var targetDistance = offset.length();
335 |
336 | // half of the fov is center to top of screen
337 | targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );
338 |
339 | // we actually don't use screenWidth, since perspective camera is fixed to screen height
340 | panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );
341 | panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );
342 |
343 | } else if ( scope.object instanceof THREE.OrthographicCamera ) {
344 |
345 | // orthographic
346 | panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );
347 | panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );
348 |
349 | } else {
350 |
351 | // camera neither orthographic nor perspective
352 | console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
353 | scope.enablePan = false;
354 |
355 | }
356 |
357 | };
358 |
359 | }();
360 |
361 | function dollyIn( dollyScale ) {
362 |
363 | if ( scope.object instanceof THREE.PerspectiveCamera ) {
364 |
365 | scale /= dollyScale;
366 |
367 | } else if ( scope.object instanceof THREE.OrthographicCamera ) {
368 |
369 | scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );
370 | scope.object.updateProjectionMatrix();
371 | zoomChanged = true;
372 |
373 | } else {
374 |
375 | console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
376 | scope.enableZoom = false;
377 |
378 | }
379 |
380 | }
381 |
382 | function dollyOut( dollyScale ) {
383 |
384 | if ( scope.object instanceof THREE.PerspectiveCamera ) {
385 |
386 | scale *= dollyScale;
387 |
388 | } else if ( scope.object instanceof THREE.OrthographicCamera ) {
389 |
390 | scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );
391 | scope.object.updateProjectionMatrix();
392 | zoomChanged = true;
393 |
394 | } else {
395 |
396 | console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
397 | scope.enableZoom = false;
398 |
399 | }
400 |
401 | }
402 |
403 | //
404 | // event callbacks - update the object state
405 | //
406 |
407 | function handleMouseDownRotate( event ) {
408 |
409 | //console.log( 'handleMouseDownRotate' );
410 |
411 | rotateStart.set( event.clientX, event.clientY );
412 |
413 | }
414 |
415 | function handleMouseDownDolly( event ) {
416 |
417 | //console.log( 'handleMouseDownDolly' );
418 |
419 | dollyStart.set( event.clientX, event.clientY );
420 |
421 | }
422 |
423 | function handleMouseDownPan( event ) {
424 |
425 | //console.log( 'handleMouseDownPan' );
426 |
427 | panStart.set( event.clientX, event.clientY );
428 |
429 | }
430 |
431 | function handleMouseMoveRotate( event ) {
432 |
433 | //console.log( 'handleMouseMoveRotate' );
434 |
435 | rotateEnd.set( event.clientX, event.clientY );
436 | rotateDelta.subVectors( rotateEnd, rotateStart );
437 |
438 | var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
439 |
440 | // rotating across whole screen goes 360 degrees around
441 | rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
442 |
443 | // rotating up and down along whole screen attempts to go 360, but limited to 180
444 | rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
445 |
446 | rotateStart.copy( rotateEnd );
447 |
448 | scope.update();
449 |
450 | }
451 |
452 | function handleMouseMoveDolly( event ) {
453 |
454 | //console.log( 'handleMouseMoveDolly' );
455 |
456 | dollyEnd.set( event.clientX, event.clientY );
457 |
458 | dollyDelta.subVectors( dollyEnd, dollyStart );
459 |
460 | if ( dollyDelta.y > 0 ) {
461 |
462 | dollyIn( getZoomScale() );
463 |
464 | } else if ( dollyDelta.y < 0 ) {
465 |
466 | dollyOut( getZoomScale() );
467 |
468 | }
469 |
470 | dollyStart.copy( dollyEnd );
471 |
472 | scope.update();
473 |
474 | }
475 |
476 | function handleMouseMovePan( event ) {
477 |
478 | //console.log( 'handleMouseMovePan' );
479 |
480 | panEnd.set( event.clientX, event.clientY );
481 |
482 | panDelta.subVectors( panEnd, panStart );
483 |
484 | pan( panDelta.x, panDelta.y );
485 |
486 | panStart.copy( panEnd );
487 |
488 | scope.update();
489 |
490 | }
491 |
492 | function handleMouseUp( event ) {
493 |
494 | // console.log( 'handleMouseUp' );
495 |
496 | }
497 |
498 | function handleMouseWheel( event ) {
499 |
500 | // console.log( 'handleMouseWheel' );
501 |
502 | if ( event.deltaY < 0 ) {
503 |
504 | dollyOut( getZoomScale() );
505 |
506 | } else if ( event.deltaY > 0 ) {
507 |
508 | dollyIn( getZoomScale() );
509 |
510 | }
511 |
512 | scope.update();
513 |
514 | }
515 |
516 | function handleKeyDown( event ) {
517 |
518 | //console.log( 'handleKeyDown' );
519 |
520 | switch ( event.keyCode ) {
521 |
522 | case scope.keys.UP:
523 | pan( 0, scope.keyPanSpeed );
524 | scope.update();
525 | break;
526 |
527 | case scope.keys.BOTTOM:
528 | pan( 0, - scope.keyPanSpeed );
529 | scope.update();
530 | break;
531 |
532 | case scope.keys.LEFT:
533 | pan( scope.keyPanSpeed, 0 );
534 | scope.update();
535 | break;
536 |
537 | case scope.keys.RIGHT:
538 | pan( - scope.keyPanSpeed, 0 );
539 | scope.update();
540 | break;
541 |
542 | }
543 |
544 | }
545 |
546 | function handleTouchStartRotate( event ) {
547 |
548 | //console.log( 'handleTouchStartRotate' );
549 |
550 | rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
551 |
552 | }
553 |
554 | function handleTouchStartDolly( event ) {
555 |
556 | //console.log( 'handleTouchStartDolly' );
557 |
558 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
559 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
560 |
561 | var distance = Math.sqrt( dx * dx + dy * dy );
562 |
563 | dollyStart.set( 0, distance );
564 |
565 | }
566 |
567 | function handleTouchStartPan( event ) {
568 |
569 | //console.log( 'handleTouchStartPan' );
570 |
571 | panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
572 |
573 | }
574 |
575 | function handleTouchMoveRotate( event ) {
576 |
577 | //console.log( 'handleTouchMoveRotate' );
578 |
579 | rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
580 | rotateDelta.subVectors( rotateEnd, rotateStart );
581 |
582 | var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
583 |
584 | // rotating across whole screen goes 360 degrees around
585 | rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
586 |
587 | // rotating up and down along whole screen attempts to go 360, but limited to 180
588 | rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
589 |
590 | rotateStart.copy( rotateEnd );
591 |
592 | scope.update();
593 |
594 | }
595 |
596 | function handleTouchMoveDolly( event ) {
597 |
598 | //console.log( 'handleTouchMoveDolly' );
599 |
600 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
601 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
602 |
603 | var distance = Math.sqrt( dx * dx + dy * dy );
604 |
605 | dollyEnd.set( 0, distance );
606 |
607 | dollyDelta.subVectors( dollyEnd, dollyStart );
608 |
609 | if ( dollyDelta.y > 0 ) {
610 |
611 | dollyOut( getZoomScale() );
612 |
613 | } else if ( dollyDelta.y < 0 ) {
614 |
615 | dollyIn( getZoomScale() );
616 |
617 | }
618 |
619 | dollyStart.copy( dollyEnd );
620 |
621 | scope.update();
622 |
623 | }
624 |
625 | function handleTouchMovePan( event ) {
626 |
627 | //console.log( 'handleTouchMovePan' );
628 |
629 | panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
630 |
631 | panDelta.subVectors( panEnd, panStart );
632 |
633 | pan( panDelta.x, panDelta.y );
634 |
635 | panStart.copy( panEnd );
636 |
637 | scope.update();
638 |
639 | }
640 |
641 | function handleTouchEnd( event ) {
642 |
643 | //console.log( 'handleTouchEnd' );
644 |
645 | }
646 |
647 | //
648 | // event handlers - FSM: listen for events and reset state
649 | //
650 |
651 | function onMouseDown( event ) {
652 |
653 | if ( scope.enabled === false ) return;
654 |
655 | event.preventDefault();
656 |
657 | if ( event.button === scope.mouseButtons.ORBIT ) {
658 |
659 | if ( scope.enableRotate === false ) return;
660 |
661 | handleMouseDownRotate( event );
662 |
663 | state = STATE.ROTATE;
664 |
665 | } else if ( event.button === scope.mouseButtons.ZOOM ) {
666 |
667 | if ( scope.enableZoom === false ) return;
668 |
669 | handleMouseDownDolly( event );
670 |
671 | state = STATE.DOLLY;
672 |
673 | } else if ( event.button === scope.mouseButtons.PAN ) {
674 |
675 | if ( scope.enablePan === false ) return;
676 |
677 | handleMouseDownPan( event );
678 |
679 | state = STATE.PAN;
680 |
681 | }
682 |
683 | if ( state !== STATE.NONE ) {
684 |
685 | document.addEventListener( 'mousemove', onMouseMove, false );
686 | document.addEventListener( 'mouseup', onMouseUp, false );
687 |
688 | scope.dispatchEvent( startEvent );
689 |
690 | }
691 |
692 | }
693 |
694 | function onMouseMove( event ) {
695 |
696 | if ( scope.enabled === false ) return;
697 |
698 | event.preventDefault();
699 |
700 | if ( state === STATE.ROTATE ) {
701 |
702 | if ( scope.enableRotate === false ) return;
703 |
704 | handleMouseMoveRotate( event );
705 |
706 | } else if ( state === STATE.DOLLY ) {
707 |
708 | if ( scope.enableZoom === false ) return;
709 |
710 | handleMouseMoveDolly( event );
711 |
712 | } else if ( state === STATE.PAN ) {
713 |
714 | if ( scope.enablePan === false ) return;
715 |
716 | handleMouseMovePan( event );
717 |
718 | }
719 |
720 | }
721 |
722 | function onMouseUp( event ) {
723 |
724 | if ( scope.enabled === false ) return;
725 |
726 | handleMouseUp( event );
727 |
728 | document.removeEventListener( 'mousemove', onMouseMove, false );
729 | document.removeEventListener( 'mouseup', onMouseUp, false );
730 |
731 | scope.dispatchEvent( endEvent );
732 |
733 | state = STATE.NONE;
734 |
735 | }
736 |
737 | function onMouseWheel( event ) {
738 |
739 | if ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;
740 |
741 | event.preventDefault();
742 | event.stopPropagation();
743 |
744 | handleMouseWheel( event );
745 |
746 | scope.dispatchEvent( startEvent ); // not sure why these are here...
747 | scope.dispatchEvent( endEvent );
748 |
749 | }
750 |
751 | function onKeyDown( event ) {
752 |
753 | if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;
754 |
755 | handleKeyDown( event );
756 |
757 | }
758 |
759 | function onTouchStart( event ) {
760 |
761 | if ( scope.enabled === false ) return;
762 |
763 | switch ( event.touches.length ) {
764 |
765 | case 1: // one-fingered touch: rotate
766 |
767 | if ( scope.enableRotate === false ) return;
768 |
769 | handleTouchStartRotate( event );
770 |
771 | state = STATE.TOUCH_ROTATE;
772 |
773 | break;
774 |
775 | case 2: // two-fingered touch: dolly
776 |
777 | if ( scope.enableZoom === false ) return;
778 |
779 | handleTouchStartDolly( event );
780 |
781 | state = STATE.TOUCH_DOLLY;
782 |
783 | break;
784 |
785 | case 3: // three-fingered touch: pan
786 |
787 | if ( scope.enablePan === false ) return;
788 |
789 | handleTouchStartPan( event );
790 |
791 | state = STATE.TOUCH_PAN;
792 |
793 | break;
794 |
795 | default:
796 |
797 | state = STATE.NONE;
798 |
799 | }
800 |
801 | if ( state !== STATE.NONE ) {
802 |
803 | scope.dispatchEvent( startEvent );
804 |
805 | }
806 |
807 | }
808 |
809 | function onTouchMove( event ) {
810 |
811 | if ( scope.enabled === false ) return;
812 |
813 | event.preventDefault();
814 | event.stopPropagation();
815 |
816 | switch ( event.touches.length ) {
817 |
818 | case 1: // one-fingered touch: rotate
819 |
820 | if ( scope.enableRotate === false ) return;
821 | if ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...
822 |
823 | handleTouchMoveRotate( event );
824 |
825 | break;
826 |
827 | case 2: // two-fingered touch: dolly
828 |
829 | if ( scope.enableZoom === false ) return;
830 | if ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...
831 |
832 | handleTouchMoveDolly( event );
833 |
834 | break;
835 |
836 | case 3: // three-fingered touch: pan
837 |
838 | if ( scope.enablePan === false ) return;
839 | if ( state !== STATE.TOUCH_PAN ) return; // is this needed?...
840 |
841 | handleTouchMovePan( event );
842 |
843 | break;
844 |
845 | default:
846 |
847 | state = STATE.NONE;
848 |
849 | }
850 |
851 | }
852 |
853 | function onTouchEnd( event ) {
854 |
855 | if ( scope.enabled === false ) return;
856 |
857 | handleTouchEnd( event );
858 |
859 | scope.dispatchEvent( endEvent );
860 |
861 | state = STATE.NONE;
862 |
863 | }
864 |
865 | function onContextMenu( event ) {
866 |
867 | event.preventDefault();
868 |
869 | }
870 |
871 | //
872 |
873 | scope.domElement.addEventListener( 'contextmenu', onContextMenu, false );
874 |
875 | scope.domElement.addEventListener( 'mousedown', onMouseDown, false );
876 | scope.domElement.addEventListener( 'wheel', onMouseWheel, false );
877 |
878 | scope.domElement.addEventListener( 'touchstart', onTouchStart, false );
879 | scope.domElement.addEventListener( 'touchend', onTouchEnd, false );
880 | scope.domElement.addEventListener( 'touchmove', onTouchMove, false );
881 |
882 | window.addEventListener( 'keydown', onKeyDown, false );
883 |
884 | // force an update at start
885 |
886 | this.update();
887 |
888 | };
889 |
890 | THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );
891 | THREE.OrbitControls.prototype.constructor = THREE.OrbitControls;
892 |
893 | Object.defineProperties( THREE.OrbitControls.prototype, {
894 |
895 | center: {
896 |
897 | get: function () {
898 |
899 | console.warn( 'THREE.OrbitControls: .center has been renamed to .target' );
900 | return this.target;
901 |
902 | }
903 |
904 | },
905 |
906 | // backward compatibility
907 |
908 | noZoom: {
909 |
910 | get: function () {
911 |
912 | console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
913 | return ! this.enableZoom;
914 |
915 | },
916 |
917 | set: function ( value ) {
918 |
919 | console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
920 | this.enableZoom = ! value;
921 |
922 | }
923 |
924 | },
925 |
926 | noRotate: {
927 |
928 | get: function () {
929 |
930 | console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
931 | return ! this.enableRotate;
932 |
933 | },
934 |
935 | set: function ( value ) {
936 |
937 | console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
938 | this.enableRotate = ! value;
939 |
940 | }
941 |
942 | },
943 |
944 | noPan: {
945 |
946 | get: function () {
947 |
948 | console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
949 | return ! this.enablePan;
950 |
951 | },
952 |
953 | set: function ( value ) {
954 |
955 | console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
956 | this.enablePan = ! value;
957 |
958 | }
959 |
960 | },
961 |
962 | noKeys: {
963 |
964 | get: function () {
965 |
966 | console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
967 | return ! this.enableKeys;
968 |
969 | },
970 |
971 | set: function ( value ) {
972 |
973 | console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
974 | this.enableKeys = ! value;
975 |
976 | }
977 |
978 | },
979 |
980 | staticMoving: {
981 |
982 | get: function () {
983 |
984 | console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
985 | return ! this.enableDamping;
986 |
987 | },
988 |
989 | set: function ( value ) {
990 |
991 | console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
992 | this.enableDamping = ! value;
993 |
994 | }
995 |
996 | },
997 |
998 | dynamicDampingFactor: {
999 |
1000 | get: function () {
1001 |
1002 | console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
1003 | return this.dampingFactor;
1004 |
1005 | },
1006 |
1007 | set: function ( value ) {
1008 |
1009 | console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
1010 | this.dampingFactor = value;
1011 |
1012 | }
1013 |
1014 | }
1015 |
1016 | } );
1017 |
--------------------------------------------------------------------------------
/lets-make-some-noise.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Perlin noise | Fireball explosion
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
224 |
225 |
236 |
237 |
303 |
304 |
305 |
--------------------------------------------------------------------------------
/lets-make-some-noise.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spite/vertex-displacement-noise-3d-webgl-glsl-three-js/3ee8c6eb34eb1d4a8a3ccf5743c358c1c8c1b58c/lets-make-some-noise.jpg
--------------------------------------------------------------------------------
/modifying-point-over-normal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spite/vertex-displacement-noise-3d-webgl-glsl-three-js/3ee8c6eb34eb1d4a8a3ccf5743c358c1c8c1b58c/modifying-point-over-normal.jpg
--------------------------------------------------------------------------------