|
@@ -21274,6 +21274,7 @@ var cameraRPos = new Vector3();
|
|
|
* Assumes 2 cameras that are parallel and share an X-axis, and that
|
|
|
* the cameras' projection and world matrices have already been set.
|
|
|
* And that near and far planes are identical for both cameras.
|
|
|
+ * Visualization of this technique: https://computergraphics.stackexchange.com/a/4765
|
|
|
*/
|
|
|
function setProjectionFromUnion( camera, cameraL, cameraR ) {
|
|
|
|
|
@@ -21287,23 +21288,21 @@ function setProjectionFromUnion( camera, cameraL, cameraR ) {
|
|
|
|
|
|
// VR systems will have identical far and near planes, and
|
|
|
// most likely identical top and bottom frustum extents.
|
|
|
- // via: https://computergraphics.stackexchange.com/a/4765
|
|
|
+ // Use the left camera for these values.
|
|
|
var near = projL[ 14 ] / ( projL[ 10 ] - 1 );
|
|
|
var far = projL[ 14 ] / ( projL[ 10 ] + 1 );
|
|
|
+ var topFov = ( projL[ 9 ] + 1 ) / projL[ 5 ];
|
|
|
+ var bottomFov = ( projL[ 9 ] - 1 ) / projL[ 5 ];
|
|
|
|
|
|
- var leftFovL = ( projL[ 8 ] - 1 ) / projL[ 0 ];
|
|
|
- var rightFovR = ( projR[ 8 ] + 1 ) / projR[ 0 ];
|
|
|
- var leftL = near * leftFovL;
|
|
|
- var rightR = near * rightFovR;
|
|
|
- var topL = near * ( projL[ 9 ] + 1 ) / projL[ 5 ];
|
|
|
- var topR = near * ( projR[ 9 ] + 1 ) / projR[ 5 ];
|
|
|
- var bottomL = near * ( projL[ 9 ] - 1 ) / projL[ 5 ];
|
|
|
- var bottomR = near * ( projR[ 9 ] - 1 ) / projR[ 5 ];
|
|
|
+ var leftFov = ( projL[ 8 ] - 1 ) / projL[ 0 ];
|
|
|
+ var rightFov = ( projR[ 8 ] + 1 ) / projR[ 0 ];
|
|
|
+ var left = near * leftFov;
|
|
|
+ var right = near * rightFov;
|
|
|
|
|
|
// Calculate the new camera's position offset from the
|
|
|
// left camera. xOffset should be roughly half `ipd`.
|
|
|
- var zOffset = ipd / ( - leftFovL + rightFovR );
|
|
|
- var xOffset = zOffset * - leftFovL;
|
|
|
+ var zOffset = ipd / ( - leftFov + rightFov );
|
|
|
+ var xOffset = zOffset * - leftFov;
|
|
|
|
|
|
// TODO: Better way to apply this offset?
|
|
|
cameraL.matrixWorld.decompose( camera.position, camera.quaternion, camera.scale );
|
|
@@ -21317,12 +21316,12 @@ function setProjectionFromUnion( camera, cameraL, cameraR ) {
|
|
|
// although must now be relative to the new union camera.
|
|
|
var near2 = near + zOffset;
|
|
|
var far2 = far + zOffset;
|
|
|
- var left = leftL - xOffset;
|
|
|
- var right = rightR + ( ipd - xOffset );
|
|
|
- var top = Math.max( topL, topR );
|
|
|
- var bottom = Math.min( bottomL, bottomR );
|
|
|
+ var left2 = left - xOffset;
|
|
|
+ var right2 = right + ( ipd - xOffset );
|
|
|
+ var top2 = topFov * far / far2 * near2;
|
|
|
+ var bottom2 = bottomFov * far / far2 * near2;
|
|
|
|
|
|
- camera.projectionMatrix.makePerspective( left, right, top, bottom, near2, far2 );
|
|
|
+ camera.projectionMatrix.makePerspective( left2, right2, top2, bottom2, near2, far2 );
|
|
|
|
|
|
}
|
|
|
|