Search Unity

PerspectiveOffCenter

Discussion in 'Scripting' started by mehdithe, Nov 16, 2011.

  1. mehdithe

    mehdithe

    Joined:
    Jul 7, 2011
    Posts:
    25
    Hi, I would like to adapt the following code for a 45 degrees inclined screen. (here it is for a screen in front of the player)
    In fact it is for a sort of cave with a display in front of the user and a display at 45 degress.

    |
    | - > First Screen
    |
    \
    \ -> Second Screen (45degrees)
    \

    Code (csharp):
    1.  
    2.  
    3. void LateUpdate()
    4.  {
    5.  
    6.         Vector3 localCamPosMain = frontCamera.transform.InverseTransformPoint(nearClipFront.transform.position);
    7.         frontCamera.nearClipPlane = localCamPosMain.z;
    8.  
    9.         FixNearClipPlane(new Vector3(localCamPosMain.x, localCamPosMain.y, localCamPosMain.z));
    10.  }
    11.  
    12. void FixNearClipPlane(Vector3 perspectiveOffsetMain)
    13. {
    14.         float left = -windowWidth / 2 - perspectiveOffsetMain.x;
    15.         float right = left + windowWidth;
    16.         float bottom = -windowHeight / 2 - perspectiveOffsetMain.y;
    17.         float top = bottom + windowHeight;
    18.  
    19.         frontCamera.projectionMatrix = PerspectiveOffCenter(left, right, bottom, top, frontCamera.nearClipPlane,      
    20.         frontCamera.farClipPlane, perspectiveOffsetMain.z);
    21.        
    22. }
    23.  
    24.  
    Code (csharp):
    1.  
    2.  static Matrix4x4 PerspectiveOffCenter (float left, float right, float bottom, float top, float near, float far, float z)
    3.     {
    4.         float x = (2.0f * near) / (right - left);
    5.         float y = (2.0f * near) / (top - bottom);
    6.         float a = (right + left) / (right - left);
    7.         float b = (top + bottom) / (top - bottom);
    8.         float c = -(far + near) / (far - near);
    9.         float d = -(2.0f * far * near) / (far - near);
    10.         float e = -1.0f;
    11.  
    12.         Matrix4x4 m = new Matrix4x4();
    13.         m[0, 0] = x; m[0, 1] = 0.0f; m[0, 2] = a; m[0, 3] = 0.0f;
    14.         m[1, 0] = 0.0f; m[1, 1] = y; m[1, 2] = b; m[1, 3] = 0.0f;
    15.         m[2, 0] = 0.0f; m[2, 1] = 0.0f; m[2, 2] = c; m[2, 3] = d;
    16.         m[3, 0] = 0.0f; m[3, 1] = 0.0f; m[3, 2] = e; m[3, 3] = 0.0f;
    17.         return m;
    18.     }
    19.  
    Thank you in advance,
     
  2. ivkoni

    ivkoni

    Joined:
    Jan 26, 2009
    Posts:
    978
    Looks like some handsome genius wrote this code :)

    The angle at which you are looking at the 'window' doesn't matter for the off center perspective calculation. Only the position matters. Or at least this is what I think.
    If you want to change the angle of the near clip plane you can look up oblique frustum culling, but this will not change how things appear on screen (no distortion) only what is visible.
     
  3. mehdithe

    mehdithe

    Joined:
    Jul 7, 2011
    Posts:
    25
    Hi!

    Thank you for your response.. and yeah you are the genius who inspired me.. :)

    Take a Look on this two screen shot and tell me what you think :

    1/ Editor view with the representation of my 2 screens corresponding to my near clip plane (there is two cameras, same position and orientation)

    http://imageshack.us/photo/my-images/265/editorpk.jpg

    2/ The game ( Screen is split in two part H = H/2, W = W)

    http://imageshack.us/photo/my-images/141/gamefj.jpg

    Finally here is my C# class for each camera :

    Code (csharp):
    1.  
    2.  
    3. using UnityEngine;
    4. using System.Collections;
    5.  
    6. public class MonoCameraProjection : MonoBehaviour
    7. {
    8.     public Transform nearClip;
    9.  
    10.     public Transform bottomLeft;
    11.     public Transform bottomRight;
    12.     public Transform topLeft;
    13.  
    14.     public float camera_Rotation;
    15.  
    16.     void LateUpdate ()    
    17.     {
    18.         Vector3 localCamPosMain = nearClip.InverseTransformPoint(this.transform.position);
    19.         //this.camera.nearClipPlane = -localCamPosMain.z;
    20.  
    21.         FixNearClipPlane(localCamPosMain);
    22.     }
    23.  
    24.     void FixNearClipPlane(Vector3 perspectiveOffsetMain)
    25.     {
    26.         float screenDistance = Vector3.Distance(this.transform.position, nearClip.position);
    27.  
    28.         float left = (bottomLeft.position.x - this.transform.position.x) * this.camera.nearClipPlane / screenDistance;
    29.         float right = (bottomRight.position.x - this.transform.position.x) * this.camera.nearClipPlane / screenDistance;
    30.         float bottom = (bottomLeft.position.y - this.transform.position.y) * this.camera.nearClipPlane / screenDistance;
    31.         float top = (topLeft.position.y - this.transform.position.y) * this.camera.nearClipPlane / screenDistance;
    32.  
    33.         this.camera.projectionMatrix = PerspectiveOffCenter(left, right, bottom, top, this.camera.nearClipPlane, this.camera.farClipPlane, perspectiveOffsetMain.z);
    34.     }
    35.  
    36.  
    37.     static Matrix4x4 PerspectiveOffCenter (float left, float right, float bottom, float top, float near, float far, float z)
    38.     {
    39.         float x = 2.0F * near / (right - left);
    40.         float y = 2.0F * near / (top - bottom);
    41.         float a = (right + left) / (right - left);
    42.         float b = (top + bottom) / (top - bottom);
    43.         float c = -(far + near) / (far - near);
    44.         float d = -(2.0F * far * near) / (far - near);
    45.         float e = -1.0F;
    46.         Matrix4x4 m;
    47.         m = Matrix4x4.zero;
    48.         m[0, 0] = x;
    49.         m[0, 1] = 0;
    50.         m[0, 2] = a;
    51.         m[0, 3] = 0;
    52.         m[1, 0] = 0;
    53.         m[1, 1] = y;
    54.         m[1, 2] = b;
    55.         m[1, 3] = 0;
    56.         m[2, 0] = 0;
    57.         m[2, 1] = 0;
    58.         m[2, 2] = c;
    59.         m[2, 3] = d;
    60.         m[3, 0] = 0;
    61.         m[3, 1] = 0;
    62.         m[3, 2] = e;
    63.         m[3, 3] = 0;
    64.         return m;
    65.     }
    66. }
    67.  
    68.  
    Please, bring me light.. It seems to be ok for you?
     
  4. ivkoni

    ivkoni

    Joined:
    Jan 26, 2009
    Posts:
    978
  5. mehdithe

    mehdithe

    Joined:
    Jul 7, 2011
    Posts:
    25
    I'm trying to perform a dual display with two screen.

    For the inclined one, i am sure my projection matrix is right. But the rendering on the second screenshot seems not so inclined. I believe i had to test in real condition. But for the moment, i have not the possibility. That's why i would like to have your opinion.

    I see on my scene the horizontal lines which are deformed as i want. But there is no deformation on the vertical ones.

    Cheers
     
  6. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    I was interesting in implementing this, but all the links at ImageShack and Unify Community are dead. Any chance you have the Offset Vanishing Point source from the wiki @ivkoni ? Could you update the screenshots on imageshack @mehdithe ?