How to calculate stereoscopic view with custom projection matrix with only one camera

I am trying to build a stereoscopic camera setup to use in a CAVE-Projection-System. But I noticed, that when calculating the Projection-Matrix per eye i can only set one camera position per frame.

In the Screenshot you can see that the frusta of the two cameras are calculated differently for the eyes but the centerpoints are at the same location so the frustum of one of the eyes is offset by the eye-distance.

So is it possible to offset the camera for the other eye or is there any other possible way to fix this problem?


FVector loc = cam->RelativeLocation;
FQuat rot = cam->RelativeRotation.Quaternion();
FVector newRotationOffset = rot.RotateVector(FVector(0, PassOffset, 0));
loc += newRotationOffset;
FTransform transform = FTransform();

// ### Camera Rotation ###
FVector vectorRight = caveProjectionArea.bottomRight - caveProjectionArea.bottomLeft;
FVector vectorUp = (caveProjectionArea.topLeft - caveProjectionArea.bottomLeft);
FVector normal = -(FVector::CrossProduct(vectorRight, vectorUp));
FVector nnormal = -normal;

// ### Frustum calculation ###
FVector eyeToBottomLeft = caveProjectionArea.bottomLeft - loc;
FVector eyeToBottomRight = caveProjectionArea.bottomRight - loc;
FVector eyeToTopLeft = caveProjectionArea.topLeft - loc;

float distance = -(FVector::DotProduct(eyeToBottomLeft, normal));

float left = FVector::DotProduct(vectorRight, eyeToBottomLeft) * GNearClippingPlane / distance; //nearClip
float right = FVector::DotProduct(vectorRight, eyeToBottomRight) * GNearClippingPlane / distance;
float bottom = FVector::DotProduct(vectorUp, eyeToBottomLeft) * GNearClippingPlane / distance;
float top = FVector::DotProduct(vectorUp, eyeToTopLeft) * GNearClippingPlane / distance;
FMatrix newProjectionMatrix = AdjustedPerspectiveOffCenter(left, right, bottom, top, GNearClippingPlane, farClip);
FMatrix meantProjectionMatrix = PerspectiveOffCenter(left, right, bottom, top, GNearClippingPlane, farClip);

// ### FOV x ###
float fovX = FMath::RadiansToDegrees(2.0f * FMath::Atan((right - left) / (2 * GNearClippingPlane)));
float s = 1 / (FMath::Tan(fovX*0.5*(PI / 180.f)));

// ### use calculated data ###
cam->AddAdditiveOffset(transform, fovX);
// updating the projectionmatrix

The green frustum lines are for the right eye which is on the bottom of the camera view and the red lines for left view.

I don’t really understand your question. But you can try -emulatestereo in
Edit → Editor Preferences → Level Editor → Play → Play in Standalone Game,

and then set “Additional Launch Parameters” to -emulatestereo.

and then play your game in standalone mode.

How to you update the projection matrix?