Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. We are looking for your feedback about Templates! Tell us about your experiences by taking our survey.
    Dismiss Notice
  3. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

When post-processing enabled on camera, Unity ignores custom projection matrix?

Discussion in 'General Graphics' started by icefallgames, May 29, 2019.

  1. icefallgames

    icefallgames

    Joined:
    Dec 6, 2014
    Posts:
    72
    I'm using the following code to set oblique near clipping plane on a camera (not the main camera):

    camera.ResetProjectionMatrix();
    camera.projectionMatrix = camera.CalculateObliqueMatrix(clipPlaneCameraSpace);

    This works fine as long as no post processing is applied to the camera. However, when I add a PostProcessLayer to the camera, suddenly objects in front of my oblique near plane are rendered. Using the Frame Debugger, I can see that in this case the projection matrix (well, unityMatrix_VP) that is being sent to the shaders is that is as if I never set my custom projectionMatrix. That is, Unity is calling ResetProjectionMatrix internally. In fact, it seems to be calling it in camera.Render() (my camera is disabled and I render it manually). Known issue? Intentional?

    Unity 2018.3.6f1

    [edit: it seems to be happening sometime between OnPreCull and OnPreRender]
     
    Last edited: May 29, 2019
  2. icefallgames

    icefallgames

    Joined:
    Dec 6, 2014
    Posts:
    72
    Aha, looks like I answered my own question... I didn't realize the source code for the post processing stuff was available:

    Code (CSharp):
    1.  
    2. void OnPreCull()
    3.         {
    4.             // Unused in scriptable render pipelines
    5.             if (RuntimeUtilities.scriptableRenderPipelineActive)
    6.                 return;
    7.  
    8.             if (m_Camera == null || m_CurrentContext == null)
    9.                 InitLegacy();
    10.  
    11.             // Resets the projection matrix from previous frame in case TAA was enabled.
    12.             // We also need to force reset the non-jittered projection matrix here as it's not done
    13.             // when ResetProjectionMatrix() is called and will break transparent rendering if TAA
    14.             // is switched off and the FOV or any other camera property changes.
    15. #if UNITY_2018_2_OR_NEWER
    16.             if (!m_Camera.usePhysicalProperties)
    17. #endif
    18.                 m_Camera.ResetProjectionMatrix();
    19.             m_Camera.nonJitteredProjectionMatrix = m_Camera.projectionMatrix;
     
  3. Dennis_eA

    Dennis_eA

    Joined:
    Jan 17, 2011
    Posts:
    251
    Answering, because I ended up here using Google to solve my problem:
    setup an oblique frustum (custom cam matrix) + using Post Process Stack V2

    Solution: use the (new) physical camera - "Lens shift" (see Camera inspector) instead of a custom matrix in code..
     
  4. Chengqi-Li

    Chengqi-Li

    Joined:
    Mar 11, 2016
    Posts:
    1
    i don't care who my hero was. but from this moment on, you are my hero. mua~
     
  5. norman_lnh

    norman_lnh

    Joined:
    Dec 16, 2015
    Posts:
    10
    so how to fix this issue?
    I'm using the following code to mirror screen (main camera):
    void OnPreCull()
    {
    camera.ResetWorldToCameraMatrix();
    camera.ResetProjectionMatrix();
    Vector3 scale = new Vector3(flipHorizontal ? -1 : 1, 1, 1);
    camera.projectionMatrix = camera.projectionMatrix * Matrix4x4.Scale(scale);
    }
    This works fine as long as no post processing is applied to the camera too.
     
  6. UnityMaru

    UnityMaru

    Community Engagement Manager Unity Technologies

    Joined:
    Mar 16, 2016
    Posts:
    949
    Did you try the advice in the posts above you?
     
unityunity