PeppersGhostEffect.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. ( function () {
  2. /**
  3. * peppers ghost effect based on http://www.instructables.com/id/Reflective-Prism/?ALLSTEPS
  4. */
  5. class PeppersGhostEffect {
  6. constructor( renderer ) {
  7. const scope = this;
  8. scope.cameraDistance = 15;
  9. scope.reflectFromAbove = false;
  10. // Internals
  11. let _halfWidth, _width, _height;
  12. const _cameraF = new THREE.PerspectiveCamera(); //front
  13. const _cameraB = new THREE.PerspectiveCamera(); //back
  14. const _cameraL = new THREE.PerspectiveCamera(); //left
  15. const _cameraR = new THREE.PerspectiveCamera(); //right
  16. const _position = new THREE.Vector3();
  17. const _quaternion = new THREE.Quaternion();
  18. const _scale = new THREE.Vector3();
  19. // Initialization
  20. renderer.autoClear = false;
  21. this.setSize = function ( width, height ) {
  22. _halfWidth = width / 2;
  23. if ( width < height ) {
  24. _width = width / 3;
  25. _height = width / 3;
  26. } else {
  27. _width = height / 3;
  28. _height = height / 3;
  29. }
  30. renderer.setSize( width, height );
  31. };
  32. this.render = function ( scene, camera ) {
  33. if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
  34. if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
  35. camera.matrixWorld.decompose( _position, _quaternion, _scale );
  36. // front
  37. _cameraF.position.copy( _position );
  38. _cameraF.quaternion.copy( _quaternion );
  39. _cameraF.translateZ( scope.cameraDistance );
  40. _cameraF.lookAt( scene.position );
  41. // back
  42. _cameraB.position.copy( _position );
  43. _cameraB.quaternion.copy( _quaternion );
  44. _cameraB.translateZ( - scope.cameraDistance );
  45. _cameraB.lookAt( scene.position );
  46. _cameraB.rotation.z += 180 * ( Math.PI / 180 );
  47. // left
  48. _cameraL.position.copy( _position );
  49. _cameraL.quaternion.copy( _quaternion );
  50. _cameraL.translateX( - scope.cameraDistance );
  51. _cameraL.lookAt( scene.position );
  52. _cameraL.rotation.x += 90 * ( Math.PI / 180 );
  53. // right
  54. _cameraR.position.copy( _position );
  55. _cameraR.quaternion.copy( _quaternion );
  56. _cameraR.translateX( scope.cameraDistance );
  57. _cameraR.lookAt( scene.position );
  58. _cameraR.rotation.x += 90 * ( Math.PI / 180 );
  59. renderer.clear();
  60. renderer.setScissorTest( true );
  61. renderer.setScissor( _halfWidth - _width / 2, _height * 2, _width, _height );
  62. renderer.setViewport( _halfWidth - _width / 2, _height * 2, _width, _height );
  63. if ( scope.reflectFromAbove ) {
  64. renderer.render( scene, _cameraB );
  65. } else {
  66. renderer.render( scene, _cameraF );
  67. }
  68. renderer.setScissor( _halfWidth - _width / 2, 0, _width, _height );
  69. renderer.setViewport( _halfWidth - _width / 2, 0, _width, _height );
  70. if ( scope.reflectFromAbove ) {
  71. renderer.render( scene, _cameraF );
  72. } else {
  73. renderer.render( scene, _cameraB );
  74. }
  75. renderer.setScissor( _halfWidth - _width / 2 - _width, _height, _width, _height );
  76. renderer.setViewport( _halfWidth - _width / 2 - _width, _height, _width, _height );
  77. if ( scope.reflectFromAbove ) {
  78. renderer.render( scene, _cameraR );
  79. } else {
  80. renderer.render( scene, _cameraL );
  81. }
  82. renderer.setScissor( _halfWidth + _width / 2, _height, _width, _height );
  83. renderer.setViewport( _halfWidth + _width / 2, _height, _width, _height );
  84. if ( scope.reflectFromAbove ) {
  85. renderer.render( scene, _cameraL );
  86. } else {
  87. renderer.render( scene, _cameraR );
  88. }
  89. renderer.setScissorTest( false );
  90. };
  91. }
  92. }
  93. THREE.PeppersGhostEffect = PeppersGhostEffect;
  94. } )();