浏览代码

Merge pull request #5707 from Fonserbc/dev

StereoEffect - Modified to be an off-axis stereo effect
Mr.doob 10 年之前
父节点
当前提交
e00632eab0
共有 1 个文件被更改,包括 49 次插入11 次删除
  1. 49 11
      examples/js/effects/StereoEffect.js

+ 49 - 11
examples/js/effects/StereoEffect.js

@@ -2,13 +2,21 @@
  * @author alteredq / http://alteredqualia.com/
  * @authod mrdoob / http://mrdoob.com/
  * @authod arodic / http://aleksandarrodic.com/
+ * @authod fonserbc / http://fonserbc.github.io/
+ *
+ * Off-axis stereoscopic effect based on http://paulbourke.net/stereographics/stereorender/
  */
 
 THREE.StereoEffect = function ( renderer ) {
 
 	// API
 
-	this.separation = 3;
+	this.eyeSeparation = 3;
+
+	/*
+	 * Distance to the non-parallax or projection plane
+	 */
+	this.focalLength = 15;
 
 	// internals
 
@@ -21,6 +29,11 @@ THREE.StereoEffect = function ( renderer ) {
 	var _cameraL = new THREE.PerspectiveCamera();
 	var _cameraR = new THREE.PerspectiveCamera();
 
+	var _fov;
+	var _outer, _inner, _top, _bottom;
+	var _ndfl, _halfFocalWidth, _halfFocalHeight;
+	var _innerFactor, _outerFactor;
+
 	// initialization
 
 	renderer.autoClear = false;
@@ -42,27 +55,52 @@ THREE.StereoEffect = function ( renderer ) {
 	
 		camera.matrixWorld.decompose( _position, _quaternion, _scale );
 
+		// Stereo frustum calculation
+
+		// Effective fov of the camera
+		_fov = THREE.Math.radToDeg( 2 * Math.atan( Math.tan( THREE.Math.degToRad( camera.fov ) * 0.5 ) / camera.zoom ) );
+
+		_ndfl = camera.near / this.focalLength;
+		_halfFocalHeight = Math.tan( THREE.Math.degToRad( _fov ) * 0.5 ) * this.focalLength;
+		_halfFocalWidth = _halfFocalHeight * 0.5 * camera.aspect;
+
+		_top = _halfFocalHeight * _ndfl;
+		_bottom = -_top;
+		_innerFactor = ( _halfFocalWidth + this.eyeSeparation / 2.0 ) / ( _halfFocalWidth * 2.0 );
+		_outerFactor = 1.0 - _innerFactor;
+
+		_outer = _halfFocalWidth * 2.0 * _ndfl * _outerFactor;
+		_inner = _halfFocalWidth * 2.0 * _ndfl * _innerFactor;
+
 		// left
 
-		_cameraL.fov = camera.fov;
-		_cameraL.aspect = 0.5 * camera.aspect;
-		_cameraL.near = camera.near;
-		_cameraL.far = camera.far;
-		_cameraL.updateProjectionMatrix();
+		_cameraL.projectionMatrix.makeFrustum(
+			-_outer,
+			_inner,
+			_bottom,
+			_top,
+			camera.near,
+			camera.far
+		);
 
 		_cameraL.position.copy( _position );
 		_cameraL.quaternion.copy( _quaternion );
-		_cameraL.translateX( - this.separation );
+		_cameraL.translateX( - this.eyeSeparation / 2.0 );
 
 		// right
 
-		_cameraR.near = camera.near;
-		_cameraR.far = camera.far;
-		_cameraR.projectionMatrix = _cameraL.projectionMatrix;
+		_cameraR.projectionMatrix.makeFrustum(
+			-_inner,
+			_outer,
+			_bottom,
+			_top,
+			camera.near,
+			camera.far
+		);
 
 		_cameraR.position.copy( _position );
 		_cameraR.quaternion.copy( _quaternion );
-		_cameraR.translateX( this.separation );
+		_cameraR.translateX( this.eyeSeparation / 2.0 );
 
 		//