瀏覽代碼

Modified Anaglyph Renderer to use an asymmetric perspective projection. Added focal length to the equation and updated to allow for camera rotation

Mark Lundin 14 年之前
父節點
當前提交
72be2f0ad4
共有 1 個文件被更改,包括 65 次插入12 次删除
  1. 65 12
      src/extras/renderers/AnaglyphWebGLRenderer.js

+ 65 - 12
src/extras/renderers/AnaglyphWebGLRenderer.js

@@ -2,12 +2,19 @@
  * @author mrdoob / http://mrdoob.com/
  */
 
-THREE.AnaglyphWebGLRenderer = function ( parameters ) {
+THREE.AnaglyphWebGLRenderer = function ( parameters ) {	
 
 	THREE.WebGLRenderer.call( this, parameters );
 
 	var _this = this, _setSize = this.setSize, _render = this.render;
 	var _cameraL = new THREE.Camera(), _cameraR = new THREE.Camera();
+	var eyeRight = new THREE.Matrix4(),
+		eyeLeft = new THREE.Matrix4(),
+		focalLength = 125,
+		aspect, near, fov;
+	
+	_cameraL.useTarget = _cameraR.useTarget = false;
+	_cameraL.matrixAutoUpdate = _cameraR.matrixAutoUpdate = false;
 
 	var _params = { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat };
 	var _renderTargetL = new THREE.WebGLRenderTarget( 512, 512, _params ), _renderTargetR = new THREE.WebGLRenderTarget( 512, 512, _params );
@@ -74,21 +81,67 @@ THREE.AnaglyphWebGLRenderer = function ( parameters ) {
 
 	};
 
-	this.render = function ( scene, camera, renderTarget, forceClear ) {
-
-		_cameraL.projectionMatrix = camera.projectionMatrix;
+	/*
+	 * Renderer now uses an asymmetric perspective projection (http://paulbourke.net/miscellaneous/stereographics/stereorender/). 
+	 * Each camera is offset by the eye seperation and its projection matrix is also skewed asymetrically back to converge on the same
+	 * projection plane. Added a focal length parameter to, this is where the parallax is equal to 0. 
+	 */
+	this.render = function ( scene, camera, renderTarget, forceClear ) {	
+		
+		
+		camera.update( null, true );
+		
+		var hasCameraChanged = 	aspect !== camera.aspect || 
+								near !== camera.near ||
+								fov !== camera.fov;
+								
+		if( hasCameraChanged )
+		{
+		
+			aspect = camera.aspect;
+			near = camera.near;
+			fov = camera.fov;	
+		
+			var projectionMatrix = camera.projectionMatrix.clone(),
+				eyeSep = focalLength / 30 * 0.5,
+				eyeSepOnProjection = eyeSep * near / focalLength,
+				ymax = near * Math.tan( fov * Math.PI / 360 ),
+				xmin, xmax;
+
+			//translate xOffset
+			eyeRight.n14 = eyeSep;
+			eyeLeft.n14 = -eyeSep;
+	
+			//For left eye
+			xmin = -ymax * aspect + eyeSepOnProjection;
+			xmax = ymax * aspect + eyeSepOnProjection;
+			projectionMatrix.n11 = 2 * near / ( xmax - xmin );
+			projectionMatrix.n13 = ( xmax + xmin ) / ( xmax - xmin );
+			_cameraL.projectionMatrix = projectionMatrix.clone();
+			
+			//for right eye		
+			xmin = -ymax * aspect - eyeSepOnProjection;
+			xmax = ymax * aspect - eyeSepOnProjection;
+			projectionMatrix.n11 = 2 * near / ( xmax - xmin );
+			projectionMatrix.n13 = ( xmax + xmin ) / ( xmax - xmin );
+			_cameraR.projectionMatrix = projectionMatrix.clone();
+				
+		}	
+		
+		_cameraL.matrix = camera.matrixWorld.clone().multiplySelf( eyeLeft );
+		_cameraL.update(null, true);
 		_cameraL.position.copy( camera.position );
-		_cameraL.target.position.copy( camera.target.position );
-		_cameraL.translateX( - 10 );
+		_cameraL.near = near;
+		_cameraL.far = camera.far;
+		_render.call( _this, scene, _cameraL, _renderTargetL, true );
 
-		_cameraR.projectionMatrix = camera.projectionMatrix;
+		_cameraR.matrix = camera.matrixWorld.clone().multiplySelf( eyeRight );
+		_cameraR.update(null, true);
 		_cameraR.position.copy( camera.position );
-		_cameraR.target.position.copy( camera.target.position );
-		_cameraR.translateX( 10 );
-
-		_render.call( _this, scene, _cameraL, _renderTargetL, true );
+		_cameraR.near = near;
+		_cameraR.far = camera.far;
 		_render.call( _this, scene, _cameraR, _renderTargetR, true );
-
+		
 		_render.call( _this, _scene, _camera );
 
 	};