# Is it possible to shift the camera viewport?

Hey,

What I'm wanting to know is if it's possible to shift the camera viewport so I can have GUI elements on the left side and the center of the camera is rendering right-of-center on the screen?

Thanks,

Chris

Use the following script :

``````function SetVanishingPoint (cam : Camera, perspectiveOffset : Vector2) {
var m = cam.projectionMatrix;
var w = 2*cam.nearClipPlane/m.m00;
var h = 2*cam.nearClipPlane/m.m11;

var left = -w/2 - perspectiveOffset.x;
var right = left+w;
var bottom = -h/2 - perspectiveOffset.y;
var top = bottom+h;

cam.projectionMatrix = PerspectiveOffCenter(left, right, bottom, top, cam.nearClipPlane, cam.farClipPlane);
}

static function PerspectiveOffCenter (
left : float, right : float,
bottom : float, top : float,
near : float, far : float ) : Matrix4x4
{
var x =  (2.0 * near)		/ (right - left);
var y =  (2.0 * near)		/ (top - bottom);
var a =  (right + left)		/ (right - left);
var b =  (top + bottom)		/ (top - bottom);
var c = -(far + near)		/ (far - near);
var d = -(2.0 * far * near) / (far - near);
var e = -1.0;

var m : Matrix4x4;
m[0,0] =   x;  m[0,1] = 0.0;  m[0,2] = a;   m[0,3] = 0.0;
m[1,0] = 0.0;  m[1,1] =   y;  m[1,2] = b;   m[1,3] = 0.0;
m[2,0] = 0.0;  m[2,1] = 0.0;  m[2,2] = c;   m[2,3] =   d;
m[3,0] = 0.0;  m[3,1] = 0.0;  m[3,2] = e;   m[3,3] = 0.0;
return m;
}
``````

Call OffsetVanishingPoint by passing a camera and a Vector2 containing the x and y amounts that you want shifted compared to the default vanishing point. The Vector2 is an absolute offset, not a relative offset. A sample usage snippet:

``````// Do a pan from left to right
var panSpeed = .15;
var panLimit = .1;

function Start () {
var t = 0.0;
while (t < 1.0) {
t += Time.deltaTime * panSpeed;
var x = Mathf.Lerp(panLimit, -panLimit, t);
SetVanishingPoint(camera.main, Vector2(x, 0.0));
yield;
}
}
``````

Be careful, as the docs say, using projectionMatrix will make the camera no longer update its rendering based on its fieldOfView, so using this function will make the camera stick at whatever FOV it had before you used it. If you want to change the FOV after using this function, you have to call ResetProjectionMatrix first.

You can use the camera normalized view port rect on the camera to set a portion of the screen to render there. I don't know how you can shift the center without avoiding gaps, but if it is acceptable to render something else in the other rect with another camera then it's a possible way to go.

After messing around with the previous script, there was a problem in the web player when the aspect ratio changed where the camera wouldn't adjust its perspective properly. Objects would be squashed or too thin.

I ended up implementing this and now it works as intended: http://unity3d.com/support/documentation/ScriptReference/Camera-worldToCameraMatrix.html

I wasn't clear on that before and wanted to post this answer in case it helps someone in the future.

So now my camera can shift its viewport, even animate the shift when certain gui elements are on the screen. It also properly displays the perspective when the web player is resized.

Thanks!

Chris

What are the measurement units of this perspective offset?
Are they pixels of the screen? Are they somewhere in between [0, 1]. Or are they in some other intermediate coordinates?