未验证 提交 a8ec3e70 编写于 作者: M Mr.doob 提交者: GitHub

Merge pull request #15133 from jsantell/frustumfix

Increase top/bottom frustum extents for the WebVR camera union to accommodate camera's new position
...@@ -12,6 +12,7 @@ var cameraRPos = new Vector3(); ...@@ -12,6 +12,7 @@ var cameraRPos = new Vector3();
* Assumes 2 cameras that are parallel and share an X-axis, and that * Assumes 2 cameras that are parallel and share an X-axis, and that
* the cameras' projection and world matrices have already been set. * the cameras' projection and world matrices have already been set.
* And that near and far planes are identical for both cameras. * 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 ) { function setProjectionFromUnion( camera, cameraL, cameraR ) {
...@@ -25,23 +26,23 @@ function setProjectionFromUnion( camera, cameraL, cameraR ) { ...@@ -25,23 +26,23 @@ function setProjectionFromUnion( camera, cameraL, cameraR ) {
// VR systems will have identical far and near planes, and // VR systems will have identical far and near planes, and
// most likely identical top and bottom frustum extents. // 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 near = projL[ 14 ] / ( projL[ 10 ] - 1 );
var far = 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 top = near * topFov;
var bottom = near * bottomFov;
var leftFovL = ( projL[ 8 ] - 1 ) / projL[ 0 ]; var leftFov = ( projL[ 8 ] - 1 ) / projL[ 0 ];
var rightFovR = ( projR[ 8 ] + 1 ) / projR[ 0 ]; var rightFov = ( projR[ 8 ] + 1 ) / projR[ 0 ];
var leftL = near * leftFovL; var left = near * leftFov;
var rightR = near * rightFovR; var right = near * rightFov;
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 ];
// Calculate the new camera's position offset from the // Calculate the new camera's position offset from the
// left camera. xOffset should be roughly half `ipd`. // left camera. xOffset should be roughly half `ipd`.
var zOffset = ipd / ( - leftFovL + rightFovR ); var zOffset = ipd / ( - leftFov + rightFov );
var xOffset = zOffset * - leftFovL; var xOffset = zOffset * - leftFov;
// TODO: Better way to apply this offset? // TODO: Better way to apply this offset?
cameraL.matrixWorld.decompose( camera.position, camera.quaternion, camera.scale ); cameraL.matrixWorld.decompose( camera.position, camera.quaternion, camera.scale );
...@@ -55,12 +56,12 @@ function setProjectionFromUnion( camera, cameraL, cameraR ) { ...@@ -55,12 +56,12 @@ function setProjectionFromUnion( camera, cameraL, cameraR ) {
// although must now be relative to the new union camera. // although must now be relative to the new union camera.
var near2 = near + zOffset; var near2 = near + zOffset;
var far2 = far + zOffset; var far2 = far + zOffset;
var left = leftL - xOffset; var left2 = left - xOffset;
var right = rightR + ( ipd - xOffset ); var right2 = right + ( ipd - xOffset );
var top = Math.max( topL, topR ); var top2 = topFov * far / far2 * near2;
var bottom = Math.min( bottomL, bottomR ); var bottom2 = bottomFov * far / far2 * near2;
camera.projectionMatrix.makePerspective( left, right, top, bottom, near2, far2 ); camera.projectionMatrix.makePerspective( left2, right2, top2, bottom2, near2, far2 );
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册