Browse Source

Added StereoEffect.
As per discussion here in ee946579c9aed339458a984cb910d6c28df86f77

Mr.doob 13 năm trước cách đây
mục cha
commit
a0a9cb1b81

+ 26 - 0
docs/api/extras/renderers/effects/StereoEffect.html

@@ -0,0 +1,26 @@
+<h1>[name]</h1>
+
+<div class="desc">todo</div>
+
+
+<h2>Constructor</h2>
+
+<h3>[name]()</h3>
+
+
+<h2>Properties</h2>
+
+<h3>.[page:Vector3 todo]</h3>
+
+
+<h2>Methods</h2>
+
+<h3>.todo( [page:Vector3 todo] )</h3>
+<div>
+todo — todo<br />
+</div>
+
+
+<h2>Source</h2>
+
+[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 2 - 1
docs/index.html

@@ -316,7 +316,8 @@
 				"Extras / Renderers / Effects": [
 					{ name: "AnaglyphEffect", path: "extras/renderers/effects/AnaglyphEffect" },
 					{ name: "CrosseyedEffect", path: "extras/renderers/effects/CrosseyedEffect" },
-					{ name: "ParallaxBarrierEffect", path: "extras/renderers/effects/ParallaxBarrierEffect" }
+					{ name: "ParallaxBarrierEffect", path: "extras/renderers/effects/ParallaxBarrierEffect" },
+					{ name: "StereoEffect", path: "extras/renderers/effects/StereoEffect" }
 				],
 
 				"Extras / Renderers / Plugins": [

+ 1 - 1
examples/js/loaders/OBJLoader.js

@@ -294,7 +294,7 @@ THREE.OBJLoader.prototype.parse = function ( data ) {
 
 		geometry.computeCentroids();
 
-		group.add( new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: Math.random() * 0xffffff } ) ) );
+		group.add( new THREE.Mesh( geometry, new THREE.MeshLambertMaterial() ) );
 
 	}
 

+ 14 - 151
src/extras/renderers/effects/AnaglyphEffect.js

@@ -1,168 +1,31 @@
 /**
  * @author mrdoob / http://mrdoob.com/
- * @author marklundin / http://mark-lundin.com/
- * @author alteredq / http://alteredqualia.com/
  */
 
 THREE.AnaglyphEffect = function ( renderer ) {
 
-	var eyeRight = new THREE.Matrix4();
-	var eyeLeft = new THREE.Matrix4();
-	var focalLength = 125;
-	var _aspect, _near, _far, _fov;
+	var shader = [
 
-	var _cameraL = new THREE.PerspectiveCamera();
-	_cameraL.matrixAutoUpdate = false;
+		"uniform sampler2D mapLeft;",
+		"uniform sampler2D mapRight;",
+		"varying vec2 vUv;",
 
-	var _cameraR = new THREE.PerspectiveCamera();
-	_cameraR.matrixAutoUpdate = false;
+		"void main() {",
 
-	var _scene = new THREE.Scene();
+		"	vec4 colorL, colorR;",
+		"	vec2 uv = vUv;",
 
-	var _camera = new THREE.PerspectiveCamera( 53, 1, 1, 10000 );
-	_camera.position.z = 2;
-	_scene.add( _camera );
+		"	colorL = texture2D( mapLeft, uv );",
+		"	colorR = texture2D( mapRight, uv );",
 
-	var _params = { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat };
+			// http://3dtv.at/Knowhow/AnaglyphComparison_en.aspx
 
-	var _renderTargetL = new THREE.WebGLRenderTarget( 512, 512, _params );
-	var _renderTargetR = new THREE.WebGLRenderTarget( 512, 512, _params );
+		"	gl_FragColor = vec4( colorL.g * 0.7 + colorL.b * 0.3, colorR.g, colorR.b, colorL.a + colorR.a ) * 1.1;",
 
-	var _material = new THREE.ShaderMaterial( {
+		"}"
 
-		uniforms: {
+	].join("\n");
 
-			"mapLeft": { type: "t", value: 0, texture: _renderTargetL },
-			"mapRight": { type: "t", value: 1, texture: _renderTargetR }
-
-		},
-
-		vertexShader: [
-
-			"varying vec2 vUv;",
-
-			"void main() {",
-
-			"	vUv = vec2( uv.x, 1.0 - uv.y );",
-			"	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
-
-			"}"
-
-		].join("\n"),
-
-		fragmentShader: [
-
-			"uniform sampler2D mapLeft;",
-			"uniform sampler2D mapRight;",
-			"varying vec2 vUv;",
-
-			"void main() {",
-
-			"	vec4 colorL, colorR;",
-			"	vec2 uv = vUv;",
-
-			"	colorL = texture2D( mapLeft, uv );",
-			"	colorR = texture2D( mapRight, uv );",
-
-				// http://3dtv.at/Knowhow/AnaglyphComparison_en.aspx
-
-			"	gl_FragColor = vec4( colorL.g * 0.7 + colorL.b * 0.3, colorR.g, colorR.b, colorL.a + colorR.a ) * 1.1;",
-
-			"}"
-
-			].join("\n")
-
-	} );
-
-	var mesh = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), _material );
-	mesh.rotation.x = Math.PI / 2;
-	_scene.add( mesh );
-
-	this.setSize = function ( width, height ) {
-
-		_renderTargetL.width = width;
-		_renderTargetL.height = height;
-
-		_renderTargetR.width = width;
-		_renderTargetR.height = height;
-
-		renderer.setSize( width, height );
-
-	};
-
-	/*
-	 * 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 ) {
-
-		scene.updateMatrixWorld();
-
-		var hasCameraChanged = ( _aspect !== camera.aspect ) || ( _near !== camera.near ) || ( _far !== camera.far ) || ( _fov !== camera.fov );
-
-		if ( hasCameraChanged ) {
-
-			_aspect = camera.aspect;
-			_near = camera.near;
-			_far = camera.far;
-			_fov = camera.fov;
-
-			var projectionMatrix = camera.projectionMatrix.clone();
-			var eyeSep = focalLength / 30 * 0.5;
-			var eyeSepOnProjection = eyeSep * _near / focalLength;
-			var ymax = _near * Math.tan( _fov * Math.PI / 360 );
-			var xmin, xmax;
-
-			// translate xOffset
-
-			eyeRight.elements[12] = eyeSep;
-			eyeLeft.elements[12] = -eyeSep;
-
-			// for left eye
-
-			xmin = -ymax * _aspect + eyeSepOnProjection;
-			xmax = ymax * _aspect + eyeSepOnProjection;
-
-			projectionMatrix.elements[0] = 2 * _near / ( xmax - xmin );
-			projectionMatrix.elements[8] = ( xmax + xmin ) / ( xmax - xmin );
-
-			_cameraL.projectionMatrix.copy( projectionMatrix );
-
-			// for right eye
-
-			xmin = -ymax * _aspect - eyeSepOnProjection;
-			xmax = ymax * _aspect - eyeSepOnProjection;
-
-			projectionMatrix.elements[0] = 2 * _near / ( xmax - xmin );
-			projectionMatrix.elements[8] = ( xmax + xmin ) / ( xmax - xmin );
-
-			_cameraR.projectionMatrix.copy( projectionMatrix );
-
-		}
-
-		_cameraL.matrixWorld.copy( camera.matrixWorld ).multiplySelf( eyeLeft );
-		_cameraL.position.copy( camera.position );
-		_cameraL.near = camera.near;
-		_cameraL.far = camera.far;
-
-		renderer.render( scene, _cameraL, _renderTargetL, true );
-
-		_cameraR.matrixWorld.copy( camera.matrixWorld ).multiplySelf( eyeRight );
-		_cameraR.position.copy( camera.position );
-		_cameraR.near = camera.near;
-		_cameraR.far = camera.far;
-
-		renderer.render( scene, _cameraR, _renderTargetR, true );
-
-		_scene.updateMatrixWorld();
-
-		renderer.render( _scene, _camera );
-
-	};
+	return new THREE.StereoEffect( renderer, shader );
 
 };

+ 14 - 150
src/extras/renderers/effects/ParallaxBarrierEffect.js

@@ -1,169 +1,33 @@
 /**
  * @author mrdoob / http://mrdoob.com/
- * @author marklundin / http://mark-lundin.com/
- * @author alteredq / http://alteredqualia.com/
  */
 
 THREE.ParallaxBarrierEffect = function ( renderer ) {
 
-	var eyeRight = new THREE.Matrix4();
-	var eyeLeft = new THREE.Matrix4();
-	var focalLength = 125;
-	var _aspect, _near, _far, _fov;
+	var shader = [
 
-	var _cameraL = new THREE.PerspectiveCamera();
-	_cameraL.matrixAutoUpdate = false;
+		"uniform sampler2D mapLeft;",
+		"uniform sampler2D mapRight;",
+		"varying vec2 vUv;",
 
-	var _cameraR = new THREE.PerspectiveCamera();
-	_cameraR.matrixAutoUpdate = false;
+		"void main() {",
 
-	var _scene = new THREE.Scene();
+		"	vec2 uv = vUv;",
 
-	var _camera = new THREE.PerspectiveCamera( 53, 1, 1, 10000 );
-	_camera.position.z = 2;
-	_scene.add( _camera );
+		"	if ( ( mod( gl_FragCoord.x, 2.0 ) ) > 1.00 ) {",
 
-	var _params = { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat };
+		"		gl_FragColor = texture2D( mapLeft, uv );",
 
-	var _renderTargetL = new THREE.WebGLRenderTarget( 512, 512, _params );
-	var _renderTargetR = new THREE.WebGLRenderTarget( 512, 512, _params );
+		"	} else {",
 
-	var _material = new THREE.ShaderMaterial( {
+		"		gl_FragColor = texture2D( mapRight, uv );",
 
-		uniforms: {
+		"	}",
 
-			"mapLeft": { type: "t", value: 0, texture: _renderTargetL },
-			"mapRight": { type: "t", value: 1, texture: _renderTargetR }
+		"}"
 
-		},
+	].join("\n");
 
-		vertexShader: [
-
-			"varying vec2 vUv;",
-
-			"void main() {",
-
-			"	vUv = vec2( uv.x, 1.0 - uv.y );",
-			"	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
-
-			"}"
-
-		].join("\n"),
-
-		fragmentShader: [
-
-			"uniform sampler2D mapLeft;",
-			"uniform sampler2D mapRight;",
-			"varying vec2 vUv;",
-
-			"void main() {",
-
-			"	vec2 uv = vUv;",
-
-			"	if ( ( mod( gl_FragCoord.x, 2.0 ) ) > 1.00 ) {",
-
-			"		gl_FragColor = texture2D( mapLeft, uv );",
-
-			"	} else {",
-
-			"		gl_FragColor = texture2D( mapRight, uv );",
-
-			"	}",
-
-			"}"
-
-			].join("\n")
-
-	} );
-
-	var mesh = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), _material );
-	mesh.rotation.x = Math.PI / 2;
-
-	_scene.add( mesh );
-
-	this.setSize = function ( width, height ) {
-
-		_renderTargetL.width = width;
-		_renderTargetL.height = height;
-
-		_renderTargetR.width = width;
-		_renderTargetR.height = height;
-
-		renderer.setSize( width, height );
-
-	};
-
-	/*
-	 * 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 ) {
-
-		var hasCameraChanged = ( _aspect !== camera.aspect ) || ( _near !== camera.near ) || ( _far !== camera.far ) || ( _fov !== camera.fov );
-
-		if ( hasCameraChanged ) {
-
-			_aspect = camera.aspect;
-			_near = camera.near;
-			_far = camera.far;
-			_fov = camera.fov;
-
-			var projectionMatrix = camera.projectionMatrix.clone();
-			var eyeSep = focalLength / 30 * 0.5;
-			var eyeSepOnProjection = eyeSep * _near / focalLength;
-			var ymax = _near * Math.tan( _fov * Math.PI / 360 );
-			var xmin, xmax;
-
-			// translate xOffset
-
-			eyeRight.elements[12] = eyeSep;
-			eyeLeft.elements[12] = -eyeSep;
-
-			// for left eye
-
-			xmin = -ymax * _aspect + eyeSepOnProjection;
-			xmax = ymax * _aspect + eyeSepOnProjection;
-
-			projectionMatrix.elements[0] = 2 * _near / ( xmax - xmin );
-			projectionMatrix.elements[8] = ( xmax + xmin ) / ( xmax - xmin );
-
-			_cameraL.projectionMatrix.copy( projectionMatrix );
-
-			// for right eye
-
-			xmin = -ymax * _aspect - eyeSepOnProjection;
-			xmax = ymax * _aspect - eyeSepOnProjection;
-
-			projectionMatrix.elements[0] = 2 * _near / ( xmax - xmin );
-			projectionMatrix.elements[8] = ( xmax + xmin ) / ( xmax - xmin );
-
-			_cameraR.projectionMatrix.copy( projectionMatrix );
-
-		}
-
-		_cameraL.matrixWorld.copy( camera.matrixWorld ).multiplySelf( eyeLeft );
-		_cameraL.position.copy( camera.position );
-		_cameraL.near = camera.near;
-		_cameraL.far = camera.far;
-
-		renderer.render( scene, _cameraL, _renderTargetL, true );
-
-		_cameraR.matrixWorld.copy( camera.matrixWorld ).multiplySelf( eyeRight );
-		_cameraR.position.copy( camera.position );
-		_cameraR.near = camera.near;
-		_cameraR.far = camera.far;
-
-		renderer.render( scene, _cameraR, _renderTargetR, true );
-
-		_scene.updateMatrixWorld();
-
-		renderer.render( _scene, _camera );
-
-	};
+	return new THREE.StereoEffect( renderer, shader );
 
 };

+ 148 - 0
src/extras/renderers/effects/StereoEffect.js

@@ -0,0 +1,148 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ * @author marklundin / http://mark-lundin.com/
+ * @author alteredq / http://alteredqualia.com/
+ */
+
+THREE.StereoEffect = function ( renderer, fragmentShader ) {
+
+	var eyeRight = new THREE.Matrix4();
+	var eyeLeft = new THREE.Matrix4();
+	var focalLength = 125;
+	var _aspect, _near, _far, _fov;
+
+	var _cameraL = new THREE.PerspectiveCamera();
+	_cameraL.matrixAutoUpdate = false;
+
+	var _cameraR = new THREE.PerspectiveCamera();
+	_cameraR.matrixAutoUpdate = false;
+
+	var _scene = new THREE.Scene();
+
+	var _camera = new THREE.PerspectiveCamera( 53, 1, 1, 10000 );
+	_camera.position.z = 2;
+	_scene.add( _camera );
+
+	var _params = { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat };
+
+	var _renderTargetL = new THREE.WebGLRenderTarget( 512, 512, _params );
+	var _renderTargetR = new THREE.WebGLRenderTarget( 512, 512, _params );
+
+	var _material = new THREE.ShaderMaterial( {
+
+		uniforms: {
+
+			"mapLeft": { type: "t", value: 0, texture: _renderTargetL },
+			"mapRight": { type: "t", value: 1, texture: _renderTargetR }
+
+		},
+
+		vertexShader: [
+
+			"varying vec2 vUv;",
+
+			"void main() {",
+
+			"	vUv = vec2( uv.x, 1.0 - uv.y );",
+			"	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
+
+			"}"
+
+		].join("\n"),
+
+		fragmentShader: fragmentShader
+
+	} );
+
+	var mesh = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), _material );
+	mesh.rotation.x = Math.PI / 2;
+	_scene.add( mesh );
+
+	this.setSize = function ( width, height ) {
+
+		_renderTargetL.width = width;
+		_renderTargetL.height = height;
+
+		_renderTargetR.width = width;
+		_renderTargetR.height = height;
+
+		renderer.setSize( width, height );
+
+	};
+
+	/*
+	 * 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 ) {
+
+		scene.updateMatrixWorld();
+
+		var hasCameraChanged = ( _aspect !== camera.aspect ) || ( _near !== camera.near ) || ( _far !== camera.far ) || ( _fov !== camera.fov );
+
+		if ( hasCameraChanged ) {
+
+			_aspect = camera.aspect;
+			_near = camera.near;
+			_far = camera.far;
+			_fov = camera.fov;
+
+			var projectionMatrix = camera.projectionMatrix.clone();
+			var eyeSep = focalLength / 30 * 0.5;
+			var eyeSepOnProjection = eyeSep * _near / focalLength;
+			var ymax = _near * Math.tan( _fov * Math.PI / 360 );
+			var xmin, xmax;
+
+			// translate xOffset
+
+			eyeRight.elements[12] = eyeSep;
+			eyeLeft.elements[12] = -eyeSep;
+
+			// for left eye
+
+			xmin = -ymax * _aspect + eyeSepOnProjection;
+			xmax = ymax * _aspect + eyeSepOnProjection;
+
+			projectionMatrix.elements[0] = 2 * _near / ( xmax - xmin );
+			projectionMatrix.elements[8] = ( xmax + xmin ) / ( xmax - xmin );
+
+			_cameraL.projectionMatrix.copy( projectionMatrix );
+
+			// for right eye
+
+			xmin = -ymax * _aspect - eyeSepOnProjection;
+			xmax = ymax * _aspect - eyeSepOnProjection;
+
+			projectionMatrix.elements[0] = 2 * _near / ( xmax - xmin );
+			projectionMatrix.elements[8] = ( xmax + xmin ) / ( xmax - xmin );
+
+			_cameraR.projectionMatrix.copy( projectionMatrix );
+
+		}
+
+		_cameraL.matrixWorld.copy( camera.matrixWorld ).multiplySelf( eyeLeft );
+		_cameraL.position.copy( camera.position );
+		_cameraL.near = camera.near;
+		_cameraL.far = camera.far;
+
+		renderer.render( scene, _cameraL, _renderTargetL, true );
+
+		_cameraR.matrixWorld.copy( camera.matrixWorld ).multiplySelf( eyeRight );
+		_cameraR.position.copy( camera.position );
+		_cameraR.near = camera.near;
+		_cameraR.far = camera.far;
+
+		renderer.render( scene, _cameraR, _renderTargetR, true );
+
+		_scene.updateMatrixWorld();
+
+		renderer.render( _scene, _camera );
+
+	};
+
+};

+ 1 - 0
utils/build.py

@@ -136,6 +136,7 @@ EXTRAS_FILES = [
 'extras/renderers/effects/AnaglyphEffect.js',
 'extras/renderers/effects/CrosseyedEffect.js',
 'extras/renderers/effects/ParallaxBarrierEffect.js',
+'extras/renderers/effects/StereoEffect.js',
 'extras/renderers/plugins/LensFlarePlugin.js',
 'extras/renderers/plugins/ShadowMapPlugin.js',
 'extras/renderers/plugins/SpritePlugin.js',