Search Unity

Question Renderer Feature: How to Set Up Reflection Oblique Matrix?

Discussion in 'Universal Render Pipeline' started by matjumon, Apr 27, 2021.

  1. matjumon

    matjumon

    Joined:
    Mar 20, 2019
    Posts:
    15
    Hi all. I am working on implementing planar reflections as a URP Renderer Feature. However, after weeks of work I haven't found a way of getting through this roadblock. I am testing this in 2021.1.1 with URP 11.0.0 at the time of writing, but I have run into the same issues while testing in Unity 2020.2 and 2020.3 as well.

    I am using a reflection matrix to flip the camera's View Matrix with respect to the mirror plane, and then using it to calculate new Oblique Projection and Culling matrices. However, once I try to apply the Oblique Projection Matrix, the rendered geometry clipped completely wrong, with the clipping plane nowhere near the expected.


    Incorrect clipping in the Renderer Feature (Frame Debug view)


    Incorrect clipping in the Renderer Feature (Scene view). The shader flips the image - notice how the image's position matches but the clipping is wrong


    Naturally, I thought I must be computing something wrong, so I tried recreating the setup using a second camera. I mirrored its transform respect to the original camera, computed its oblique matrix, and... it renders correctly. I then double-checked and fixed every matrix in my Renderer Feature: I made sure the View, Projection, and Culling Matrices were identical between the (working) second camera and the Renderer Feature. Yet, the Renderer Feature still renders wrong.


    Correct output from the separate camera setup, for reference. It's using the exact same matrices.

    Given the lack of proper documentation of the Renderer Feature API, I tried a few different functions with varying results:
    • Using RenderingUtils.SetViewAndProjectionMatrices to set the mirrored view and oblique projection matrices produces the correct view, but incorrect clipping
    • Using RenderingUtils.SetViewAndProjectionMatrices to set the original view and oblique projection matrices produces the non-mirrored view, with the clipping plane in the right position but with wrong normal.
    • Using cmd.SetViewMatrix and cmd.SetProjectionMatrix to set the mirrored view and oblique projection matrices produces the correct clipping but the camera view does not match the correct mirrored position (instead, it moves around opposite to the intended movement - no point of view manages to make the reflection match its correct position)
    • Using either cmd.SetViewMatrix or cmd.SetProjectionMatrix break the camera's positioning, even if called before or after RenderingUtils.SetViewAndProjectionMatrices

    Using the CommandBuffer methods instead of RenderingUtils. Correct clipping, but the view and depth are wrong.

    Looking at RenderingUtils.SetViewAndProjectionMatrices's source code, I see it doesn't even call cmd.SetViewMatrix or cmd.SetProjectionMatrix, instead opting for cmd.SetGlobalMatrix. The CommandBuffer methods are part of the core engine so I can't tell whether they are also using cmd.SetGlobalMatrix the same way RenderingUtils.SetViewAndProjectionMatrices does...

    So in summary:

    • Trying to make a Planar Reflection Renderer Feature
    • Separate camera set up produces the correct image (but has its own reasons to not be a viable option for my needs)
    • Exact same matrices produce incorrect results when used inside the RendererFeature
    • Different methods produce different results using the same matrices, but none of them are correct.
    Anyone have any clues? Am I doing something terribly wrong? Or is there something broken within the RendererFeature API? Any insight is much appreciated!

    (Thanks in advance, I am legit going insane over this...)