Doodle3D-Slicer/three.js-master/examples/js/effects/ParallaxBarrierEffect.js
2015-06-12 15:58:26 +02:00

172 lines
4.3 KiB
JavaScript
Executable File

/**
* @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 _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: _renderTargetL },
"mapRight": { type: "t", value: _renderTargetR }
},
vertexShader: [
"varying vec2 vUv;",
"void main() {",
" vUv = vec2( uv.x, 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.y, 2.0 ) ) > 1.00 ) {",
" gl_FragColor = texture2D( mapLeft, uv );",
" } else {",
" gl_FragColor = texture2D( mapRight, uv );",
" }",
"}"
].join("\n")
} );
var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), _material );
_scene.add( mesh );
this.setSize = function ( width, height ) {
_renderTargetL = new THREE.WebGLRenderTarget( width, height, _params );
_renderTargetR = new THREE.WebGLRenderTarget( width, height, _params );
_material.uniforms[ "mapLeft" ].value = _renderTargetL;
_material.uniforms[ "mapRight" ].value = _renderTargetR;
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();
if ( camera.parent === undefined ) camera.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( THREE.Math.degToRad( _fov * 0.5 ) );
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 ).multiply( 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 ).multiply( 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 );
};
};