|
@@ -117,159 +117,164 @@ THREE.Mirror = function ( renderer, camera, options ) {
|
|
|
};
|
|
|
|
|
|
THREE.Mirror.prototype = Object.create( THREE.Object3D.prototype );
|
|
|
-THREE.Mirror.prototype.constructor = THREE.Mirror;
|
|
|
|
|
|
-THREE.Mirror.prototype.renderWithMirror = function ( otherMirror ) {
|
|
|
+Object.assign( THREE.Mirror.prototype, {
|
|
|
|
|
|
- // update the mirror matrix to mirror the current view
|
|
|
- this.updateTextureMatrix();
|
|
|
- this.matrixNeedsUpdate = false;
|
|
|
+ constructor: THREE.Mirror,
|
|
|
|
|
|
- // set the camera of the other mirror so the mirrored view is the reference view
|
|
|
- var tempCamera = otherMirror.camera;
|
|
|
- otherMirror.camera = this.mirrorCamera;
|
|
|
+ renderWithMirror: function ( otherMirror ) {
|
|
|
|
|
|
- // render the other mirror in temp texture
|
|
|
- otherMirror.renderTemp();
|
|
|
- otherMirror.material.uniforms.mirrorSampler.value = otherMirror.renderTarget2.texture;
|
|
|
+ // update the mirror matrix to mirror the current view
|
|
|
+ this.updateTextureMatrix();
|
|
|
+ this.matrixNeedsUpdate = false;
|
|
|
|
|
|
- // render the current mirror
|
|
|
- this.render();
|
|
|
- this.matrixNeedsUpdate = true;
|
|
|
+ // set the camera of the other mirror so the mirrored view is the reference view
|
|
|
+ var tempCamera = otherMirror.camera;
|
|
|
+ otherMirror.camera = this.mirrorCamera;
|
|
|
|
|
|
- // restore material and camera of other mirror
|
|
|
- otherMirror.material.uniforms.mirrorSampler.value = otherMirror.renderTarget.texture;
|
|
|
- otherMirror.camera = tempCamera;
|
|
|
+ // render the other mirror in temp texture
|
|
|
+ otherMirror.renderTemp();
|
|
|
+ otherMirror.material.uniforms.mirrorSampler.value = otherMirror.renderTarget2.texture;
|
|
|
|
|
|
- // restore texture matrix of other mirror
|
|
|
- otherMirror.updateTextureMatrix();
|
|
|
+ // render the current mirror
|
|
|
+ this.render();
|
|
|
+ this.matrixNeedsUpdate = true;
|
|
|
|
|
|
-};
|
|
|
+ // restore material and camera of other mirror
|
|
|
+ otherMirror.material.uniforms.mirrorSampler.value = otherMirror.renderTarget.texture;
|
|
|
+ otherMirror.camera = tempCamera;
|
|
|
|
|
|
-THREE.Mirror.prototype.updateTextureMatrix = function () {
|
|
|
+ // restore texture matrix of other mirror
|
|
|
+ otherMirror.updateTextureMatrix();
|
|
|
|
|
|
- this.updateMatrixWorld();
|
|
|
- this.camera.updateMatrixWorld();
|
|
|
+ },
|
|
|
|
|
|
- this.mirrorWorldPosition.setFromMatrixPosition( this.matrixWorld );
|
|
|
- this.cameraWorldPosition.setFromMatrixPosition( this.camera.matrixWorld );
|
|
|
+ updateTextureMatrix: function () {
|
|
|
|
|
|
- this.rotationMatrix.extractRotation( this.matrixWorld );
|
|
|
+ this.updateMatrixWorld();
|
|
|
+ this.camera.updateMatrixWorld();
|
|
|
|
|
|
- this.normal.set( 0, 0, 1 );
|
|
|
- this.normal.applyMatrix4( this.rotationMatrix );
|
|
|
+ this.mirrorWorldPosition.setFromMatrixPosition( this.matrixWorld );
|
|
|
+ this.cameraWorldPosition.setFromMatrixPosition( this.camera.matrixWorld );
|
|
|
|
|
|
- var view = this.mirrorWorldPosition.clone().sub( this.cameraWorldPosition );
|
|
|
- view.reflect( this.normal ).negate();
|
|
|
- view.add( this.mirrorWorldPosition );
|
|
|
+ this.rotationMatrix.extractRotation( this.matrixWorld );
|
|
|
|
|
|
- this.rotationMatrix.extractRotation( this.camera.matrixWorld );
|
|
|
+ this.normal.set( 0, 0, 1 );
|
|
|
+ this.normal.applyMatrix4( this.rotationMatrix );
|
|
|
|
|
|
- this.lookAtPosition.set( 0, 0, - 1 );
|
|
|
- this.lookAtPosition.applyMatrix4( this.rotationMatrix );
|
|
|
- this.lookAtPosition.add( this.cameraWorldPosition );
|
|
|
+ var view = this.mirrorWorldPosition.clone().sub( this.cameraWorldPosition );
|
|
|
+ view.reflect( this.normal ).negate();
|
|
|
+ view.add( this.mirrorWorldPosition );
|
|
|
|
|
|
- var target = this.mirrorWorldPosition.clone().sub( this.lookAtPosition );
|
|
|
- target.reflect( this.normal ).negate();
|
|
|
- target.add( this.mirrorWorldPosition );
|
|
|
+ this.rotationMatrix.extractRotation( this.camera.matrixWorld );
|
|
|
|
|
|
- this.up.set( 0, - 1, 0 );
|
|
|
- this.up.applyMatrix4( this.rotationMatrix );
|
|
|
- this.up.reflect( this.normal ).negate();
|
|
|
+ this.lookAtPosition.set( 0, 0, - 1 );
|
|
|
+ this.lookAtPosition.applyMatrix4( this.rotationMatrix );
|
|
|
+ this.lookAtPosition.add( this.cameraWorldPosition );
|
|
|
|
|
|
- this.mirrorCamera.position.copy( view );
|
|
|
- this.mirrorCamera.up = this.up;
|
|
|
- this.mirrorCamera.lookAt( target );
|
|
|
+ var target = this.mirrorWorldPosition.clone().sub( this.lookAtPosition );
|
|
|
+ target.reflect( this.normal ).negate();
|
|
|
+ target.add( this.mirrorWorldPosition );
|
|
|
|
|
|
- this.mirrorCamera.updateProjectionMatrix();
|
|
|
- this.mirrorCamera.updateMatrixWorld();
|
|
|
- this.mirrorCamera.matrixWorldInverse.getInverse( this.mirrorCamera.matrixWorld );
|
|
|
+ this.up.set( 0, - 1, 0 );
|
|
|
+ this.up.applyMatrix4( this.rotationMatrix );
|
|
|
+ this.up.reflect( this.normal ).negate();
|
|
|
|
|
|
- // Update the texture matrix
|
|
|
- this.textureMatrix.set(
|
|
|
- 0.5, 0.0, 0.0, 0.5,
|
|
|
- 0.0, 0.5, 0.0, 0.5,
|
|
|
- 0.0, 0.0, 0.5, 0.5,
|
|
|
- 0.0, 0.0, 0.0, 1.0
|
|
|
- );
|
|
|
- this.textureMatrix.multiply( this.mirrorCamera.projectionMatrix );
|
|
|
- this.textureMatrix.multiply( this.mirrorCamera.matrixWorldInverse );
|
|
|
+ this.mirrorCamera.position.copy( view );
|
|
|
+ this.mirrorCamera.up = this.up;
|
|
|
+ this.mirrorCamera.lookAt( target );
|
|
|
|
|
|
- // Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html
|
|
|
- // Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf
|
|
|
- this.mirrorPlane.setFromNormalAndCoplanarPoint( this.normal, this.mirrorWorldPosition );
|
|
|
- this.mirrorPlane.applyMatrix4( this.mirrorCamera.matrixWorldInverse );
|
|
|
+ this.mirrorCamera.updateProjectionMatrix();
|
|
|
+ this.mirrorCamera.updateMatrixWorld();
|
|
|
+ this.mirrorCamera.matrixWorldInverse.getInverse( this.mirrorCamera.matrixWorld );
|
|
|
|
|
|
- this.clipPlane.set( this.mirrorPlane.normal.x, this.mirrorPlane.normal.y, this.mirrorPlane.normal.z, this.mirrorPlane.constant );
|
|
|
+ // Update the texture matrix
|
|
|
+ this.textureMatrix.set(
|
|
|
+ 0.5, 0.0, 0.0, 0.5,
|
|
|
+ 0.0, 0.5, 0.0, 0.5,
|
|
|
+ 0.0, 0.0, 0.5, 0.5,
|
|
|
+ 0.0, 0.0, 0.0, 1.0
|
|
|
+ );
|
|
|
+ this.textureMatrix.multiply( this.mirrorCamera.projectionMatrix );
|
|
|
+ this.textureMatrix.multiply( this.mirrorCamera.matrixWorldInverse );
|
|
|
|
|
|
- var q = new THREE.Vector4();
|
|
|
- var projectionMatrix = this.mirrorCamera.projectionMatrix;
|
|
|
+ // Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html
|
|
|
+ // Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf
|
|
|
+ this.mirrorPlane.setFromNormalAndCoplanarPoint( this.normal, this.mirrorWorldPosition );
|
|
|
+ this.mirrorPlane.applyMatrix4( this.mirrorCamera.matrixWorldInverse );
|
|
|
|
|
|
- q.x = ( Math.sign( this.clipPlane.x ) + projectionMatrix.elements[ 8 ] ) / projectionMatrix.elements[ 0 ];
|
|
|
- q.y = ( Math.sign( this.clipPlane.y ) + projectionMatrix.elements[ 9 ] ) / projectionMatrix.elements[ 5 ];
|
|
|
- q.z = - 1.0;
|
|
|
- q.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ];
|
|
|
+ this.clipPlane.set( this.mirrorPlane.normal.x, this.mirrorPlane.normal.y, this.mirrorPlane.normal.z, this.mirrorPlane.constant );
|
|
|
|
|
|
- // Calculate the scaled plane vector
|
|
|
- var c = new THREE.Vector4();
|
|
|
- c = this.clipPlane.multiplyScalar( 2.0 / this.clipPlane.dot( q ) );
|
|
|
+ var q = new THREE.Vector4();
|
|
|
+ var projectionMatrix = this.mirrorCamera.projectionMatrix;
|
|
|
|
|
|
- // Replacing the third row of the projection matrix
|
|
|
- projectionMatrix.elements[ 2 ] = c.x;
|
|
|
- projectionMatrix.elements[ 6 ] = c.y;
|
|
|
- projectionMatrix.elements[ 10 ] = c.z + 1.0 - this.clipBias;
|
|
|
- projectionMatrix.elements[ 14 ] = c.w;
|
|
|
+ q.x = ( Math.sign( this.clipPlane.x ) + projectionMatrix.elements[ 8 ] ) / projectionMatrix.elements[ 0 ];
|
|
|
+ q.y = ( Math.sign( this.clipPlane.y ) + projectionMatrix.elements[ 9 ] ) / projectionMatrix.elements[ 5 ];
|
|
|
+ q.z = - 1.0;
|
|
|
+ q.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ];
|
|
|
|
|
|
-};
|
|
|
+ // Calculate the scaled plane vector
|
|
|
+ var c = new THREE.Vector4();
|
|
|
+ c = this.clipPlane.multiplyScalar( 2.0 / this.clipPlane.dot( q ) );
|
|
|
|
|
|
-THREE.Mirror.prototype.render = function () {
|
|
|
+ // Replacing the third row of the projection matrix
|
|
|
+ projectionMatrix.elements[ 2 ] = c.x;
|
|
|
+ projectionMatrix.elements[ 6 ] = c.y;
|
|
|
+ projectionMatrix.elements[ 10 ] = c.z + 1.0 - this.clipBias;
|
|
|
+ projectionMatrix.elements[ 14 ] = c.w;
|
|
|
|
|
|
- if ( this.matrixNeedsUpdate ) this.updateTextureMatrix();
|
|
|
+ },
|
|
|
|
|
|
- this.matrixNeedsUpdate = true;
|
|
|
+ render: function () {
|
|
|
|
|
|
- // Render the mirrored view of the current scene into the target texture
|
|
|
- var scene = this;
|
|
|
+ if ( this.matrixNeedsUpdate ) this.updateTextureMatrix();
|
|
|
|
|
|
- while ( scene.parent !== null ) {
|
|
|
+ this.matrixNeedsUpdate = true;
|
|
|
|
|
|
- scene = scene.parent;
|
|
|
+ // Render the mirrored view of the current scene into the target texture
|
|
|
+ var scene = this;
|
|
|
|
|
|
- }
|
|
|
+ while ( scene.parent !== null ) {
|
|
|
|
|
|
- if ( scene !== undefined && scene instanceof THREE.Scene ) {
|
|
|
+ scene = scene.parent;
|
|
|
|
|
|
- // We can't render ourself to ourself
|
|
|
- var visible = this.material.visible;
|
|
|
- this.material.visible = false;
|
|
|
+ }
|
|
|
|
|
|
- this.renderer.render( scene, this.mirrorCamera, this.renderTarget, true );
|
|
|
+ if ( scene !== undefined && scene instanceof THREE.Scene ) {
|
|
|
|
|
|
- this.material.visible = visible;
|
|
|
+ // We can't render ourself to ourself
|
|
|
+ var visible = this.material.visible;
|
|
|
+ this.material.visible = false;
|
|
|
|
|
|
- }
|
|
|
+ this.renderer.render( scene, this.mirrorCamera, this.renderTarget, true );
|
|
|
|
|
|
-};
|
|
|
+ this.material.visible = visible;
|
|
|
|
|
|
-THREE.Mirror.prototype.renderTemp = function () {
|
|
|
+ }
|
|
|
|
|
|
- if ( this.matrixNeedsUpdate ) this.updateTextureMatrix();
|
|
|
+ },
|
|
|
|
|
|
- this.matrixNeedsUpdate = true;
|
|
|
+ renderTemp: function () {
|
|
|
|
|
|
- // Render the mirrored view of the current scene into the target texture
|
|
|
- var scene = this;
|
|
|
+ if ( this.matrixNeedsUpdate ) this.updateTextureMatrix();
|
|
|
|
|
|
- while ( scene.parent !== null ) {
|
|
|
+ this.matrixNeedsUpdate = true;
|
|
|
|
|
|
- scene = scene.parent;
|
|
|
+ // Render the mirrored view of the current scene into the target texture
|
|
|
+ var scene = this;
|
|
|
|
|
|
- }
|
|
|
+ while ( scene.parent !== null ) {
|
|
|
+
|
|
|
+ scene = scene.parent;
|
|
|
|
|
|
- if ( scene !== undefined && scene instanceof THREE.Scene ) {
|
|
|
+ }
|
|
|
|
|
|
- this.renderer.render( scene, this.mirrorCamera, this.renderTarget2, true );
|
|
|
+ if ( scene !== undefined && scene instanceof THREE.Scene ) {
|
|
|
+
|
|
|
+ this.renderer.render( scene, this.mirrorCamera, this.renderTarget2, true );
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
|
-};
|
|
|
+} );
|