StereoCamera.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import { Matrix4 } from '../math/Matrix4.js';
  2. import { _Math } from '../math/Math.js';
  3. import { PerspectiveCamera } from './PerspectiveCamera.js';
  4. /**
  5. * @author mrdoob / http://mrdoob.com/
  6. */
  7. function StereoCamera() {
  8. this.type = 'StereoCamera';
  9. this.aspect = 1;
  10. this.eyeSep = 0.064;
  11. this.cameraL = new PerspectiveCamera();
  12. this.cameraL.layers.enable( 1 );
  13. this.cameraL.matrixAutoUpdate = false;
  14. this.cameraR = new PerspectiveCamera();
  15. this.cameraR.layers.enable( 2 );
  16. this.cameraR.matrixAutoUpdate = false;
  17. }
  18. Object.assign( StereoCamera.prototype, {
  19. update: ( function () {
  20. var instance, focus, fov, aspect, near, far, zoom, eyeSep;
  21. var eyeRight = new Matrix4();
  22. var eyeLeft = new Matrix4();
  23. return function update( camera ) {
  24. var needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||
  25. aspect !== camera.aspect * this.aspect || near !== camera.near ||
  26. far !== camera.far || zoom !== camera.zoom || eyeSep !== this.eyeSep;
  27. if ( needsUpdate ) {
  28. instance = this;
  29. focus = camera.focus;
  30. fov = camera.fov;
  31. aspect = camera.aspect * this.aspect;
  32. near = camera.near;
  33. far = camera.far;
  34. zoom = camera.zoom;
  35. // Off-axis stereoscopic effect based on
  36. // http://paulbourke.net/stereographics/stereorender/
  37. var projectionMatrix = camera.projectionMatrix.clone();
  38. eyeSep = this.eyeSep / 2;
  39. var eyeSepOnProjection = eyeSep * near / focus;
  40. var ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;
  41. var xmin, xmax;
  42. // translate xOffset
  43. eyeLeft.elements[ 12 ] = - eyeSep;
  44. eyeRight.elements[ 12 ] = eyeSep;
  45. // for left eye
  46. xmin = - ymax * aspect + eyeSepOnProjection;
  47. xmax = ymax * aspect + eyeSepOnProjection;
  48. projectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );
  49. projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );
  50. this.cameraL.projectionMatrix.copy( projectionMatrix );
  51. // for right eye
  52. xmin = - ymax * aspect - eyeSepOnProjection;
  53. xmax = ymax * aspect - eyeSepOnProjection;
  54. projectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );
  55. projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );
  56. this.cameraR.projectionMatrix.copy( projectionMatrix );
  57. }
  58. this.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );
  59. this.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );
  60. };
  61. } )()
  62. } );
  63. export { StereoCamera };