Search Unity

  1. We are migrating the Unity Forums to Unity Discussions by the end of July. Read our announcement for more information and let us know if you have any questions.
    Dismiss Notice
  2. Dismiss Notice

Camera custom projection matrix

Discussion in 'General Graphics' started by nico69, Apr 24, 2021.

  1. nico69

    nico69

    Joined:
    Oct 15, 2016
    Posts:
    9
    Hi
    I want to create a scene where all the elements of the scene cloned and rendered at a smaller size at the center.
    Here a (broken) screen of what i want to do.

    I don't want to physicaly clone the gameobjects, because the player can interact with some objects, and the interaction have exactly the same influence on the cloned area.

    For that i use a 2nd camera placed in a place that simulate the render of the same room, but smaller.
    upload_2021-4-24_22-14-27.png
    But the render is not at the right position because it's deeper on the z buffer.
    I have see that i can edit the projection matrix of the camera to allow to draw at an other height on the z buffer.
    https://answers.unity.com/questions/1359718/what-do-the-values-in-the-matrix4x4-for-cameraproj.html
    I have tried to modity the values of m22 and m23 to simulate the near and far plan of the main camera, but it don't work well.
    Here the code of the clones cameras positions and the modification of the projection matrix.

    Code (CSharp):
    1.  
    2. class CameraInfo
    3.     {
    4.         public float scale;
    5.         public Transform transform;
    6.         public Camera camera;
    7.  
    8.         public float near;
    9.         public float far;
    10.     }
    11.  
    12. class GetCameraEvent
    13. {
    14.     public Camera camera = null;
    15. }
    16.  
    17. void ProcessCameras()
    18.     {
    19.         GetCameraEvent camera = new GetCameraEvent();
    20.         Event<GetCameraEvent>.Broadcast(camera); //main camera
    21.  
    22.         Vector3 center = transform.position;
    23.         Vector3 pos = camera.camera.transform.position;
    24.         Vector3 forward = camera.camera.transform.forward;
    25.         Quaternion rotation = camera.camera.transform.rotation;
    26.  
    27.         float near = camera.camera.nearClipPlane;
    28.         float far = camera.camera.farClipPlane;
    29.  
    30. //for all cloned camera
    31.         foreach (var c in m_cameras)
    32.         {
    33.             c.transform.rotation = rotation;
    34.  
    35.             Vector3 zero = -center / c.scale + center;
    36.  
    37.             Vector3 cameraPos = pos / c.scale + zero;
    38.             c.transform.position = cameraPos;
    39.  
    40. //we use the same base projection matrix than the main camera
    41.             var mat = camera.camera.projectionMatrix;
    42.  
    43.             var dir = Vector3.Project(pos - cameraPos, forward);
    44.             float dist = dir.magnitude;
    45.             if (Vector3.Dot(dir, forward) < 0)
    46.                 dist *= -1;
    47.  
    48. //near and far plan on the same plan than the main camera
    49.             float currentNear = near + dist;
    50.             float currentFar = far + dist;
    51.  
    52.             c.near = currentNear;
    53.             c.far = currentFar;
    54.  
    55. //change matrix for z buffer
    56.             mat.m22 = -(currentFar + currentNear) / (currentFar - currentNear);
    57.             mat.m23 = -(2 * currentFar * currentNear) / (currentFar - currentNear);
    58.  
    59.             c.camera.projectionMatrix = mat;
    60.         }
    61.     }
    62.  
    Is there a way to do what i want without cloning every gameobject multiple times ?

    Sorry for my bad english, it's not my native langage.
    Thanks for your help

    Nico
     
    Last edited: Apr 24, 2021