I’ve done this before in Unity–the way to do it was to change the camera projection matrix
I copied this from somewhere, can’t remember since it was like a year ago and while it’s C# it might help you get on the right track:
using UnityEngine;
using System.Collections;
public class CameraProjection : MonoBehaviour
{
//eye
public static Transform eye;
public GameObject Tracker;
//screen
//public GameObject screenObj;
public GameObject screenBottomLeftObj;
public GameObject screenBottomRightObj;
public GameObject screenTopLeftObj;
void Update()
{
transform.position = Tracker.transform.position;
//eye tracking
eye = transform;
Vector3 eyePosition = eye.position;
//screen tracking
Vector3 screenBottomLeft = screenBottomLeftObj.transform.position;//lower left of screen
Vector3 screenBottomRight = screenBottomRightObj.transform.position;//lower right of screen
Vector3 screenTopLeft = screenTopLeftObj.transform.position;//upper left of screen
//off-axis camera projection
Matrix4x4 m = Projection(eyePosition, screenBottomLeft, screenBottomRight, screenTopLeft, camera.nearClipPlane, camera.farClipPlane);
camera.projectionMatrix = m;
}
static Matrix4x4 Projection(
Vector3 eye,
Vector3 screenBottomLeft,
Vector3 screenBottomRight,
Vector3 screenTopLeft,
float nearClip,
float farClip)
{
Matrix4x4 projectionMatrix = Matrix4x4.zero;
float left, right, bottom, top;
float screenDistance = screenBottomLeft.z - eye.z;
left = (screenBottomLeft.x - eye.x) * nearClip / screenDistance;
right = (screenBottomRight.x - eye.x) * nearClip / screenDistance;
bottom = (screenBottomLeft.y - eye.y) * nearClip / screenDistance;
top = (screenTopLeft.y - eye.y) * nearClip / screenDistance;
projectionMatrix = PerspectiveOffCenter(left, right, bottom, top, nearClip, farClip);
return projectionMatrix;
}
static Matrix4x4 ProjectionCAVE(
Vector3 eye,
Vector3 screenBottomLeft,
Vector3 screenBottomRight,
Vector3 screenTopLeft,
float nearClip,
float farClip)
{
Matrix4x4 projectionMatrix = Matrix4x4.zero;
Vector3 screenXVector;
Vector3 screenYVector;
Vector3 screenZVector;
screenXVector = screenBottomRight - screenBottomLeft;
screenYVector = screenTopLeft - screenBottomLeft;
screenXVector.Normalize();
screenYVector.Normalize();
screenZVector = Vector3.Cross(screenXVector, screenYVector);
screenZVector.Normalize();
Vector3 eyeToBottomLeft;
Vector3 eyeToBottomRight;
Vector3 eyeToTopLeft;
eyeToBottomLeft = screenBottomLeft - eye;
eyeToBottomRight = screenBottomRight - eye;
eyeToTopLeft = screenTopLeft - eye;
float eyeDistance;
eyeDistance = -Vector3.Dot(eyeToBottomLeft, screenZVector);
float left, right, bottom, top;
left = Vector3.Dot(screenXVector, eyeToBottomLeft) * nearClip / eyeDistance;
right = Vector3.Dot(screenXVector, eyeToBottomRight) * nearClip / eyeDistance;
bottom = Vector3.Dot(screenYVector, eyeToBottomLeft) * nearClip / eyeDistance;
top = Vector3.Dot(screenYVector, eyeToTopLeft) * nearClip / eyeDistance;
// glFrustum implementation
projectionMatrix = PerspectiveOffCenter(left, right, bottom, top, nearClip, farClip);
Matrix4x4 rotationMatrix;
rotationMatrix = Matrix4x4.zero;
rotationMatrix[0, 0] = screenXVector[0];
rotationMatrix[0, 1] = screenYVector[0];
rotationMatrix[0, 2] = screenZVector[0];
rotationMatrix[0, 3] = 0;
rotationMatrix[1, 0] = screenXVector[1];
rotationMatrix[1, 1] = screenYVector[1];
rotationMatrix[1, 2] = screenZVector[1];
rotationMatrix[1, 3] = 0;
rotationMatrix[2, 0] = screenXVector[2];
rotationMatrix[2, 1] = screenYVector[2];
rotationMatrix[2, 2] = screenZVector[2];
rotationMatrix[2, 3] = 0;
rotationMatrix[3, 0] = 0;
rotationMatrix[3, 1] = 0;
rotationMatrix[3, 2] = 0;
rotationMatrix[3, 3] = 1;
projectionMatrix = rotationMatrix * projectionMatrix;
//projectionMatrix = projectionMatrix * rotationMatrix;
Matrix4x4 translationMatrix;
translationMatrix = Matrix4x4.zero;
translationMatrix.SetTRS(-eye, Quaternion.identity, Vector3.zero);
projectionMatrix = translationMatrix * projectionMatrix;
return projectionMatrix;
}
static Matrix4x4 PerspectiveOffCenter(float left, float right, float bottom, float top, float near, float far)
{
float x = 2.0F * near / (right - left);
float y = 2.0F * near / (top - bottom);
float a = (right + left) / (right - left);
float b = (top + bottom) / (top - bottom);
float c = -(far + near) / (far - near);
float d = -(2.0F * far * near) / (far - near);
float e = -1.0F;
Matrix4x4 m;
m = Matrix4x4.zero;
m[0, 0] = x;
m[0, 1] = 0;
m[0, 2] = a;
m[0, 3] = 0;
m[1, 0] = 0;
m[1, 1] = y;
m[1, 2] = b;
m[1, 3] = 0;
m[2, 0] = 0;
m[2, 1] = 0;
m[2, 2] = c;
m[2, 3] = d;
m[3, 0] = 0;
m[3, 1] = 0;
m[3, 2] = e;
m[3, 3] = 0;
return m;
}
}