(URP) Cameras: Create a custom projection matrix given a bounding rectangle.

Hi,

I’m looking to modify a camera’s projection matrix to only render within a certain bounding rectangle.

The specific problem is, given 4 Vector3s which form a ‘rectangle’ in 3D space, and a camera’s projection matrix, I want to compute a new projection matrix which only renders the camera within that bounding rectangle. This is for optimization and culling purposes.


Picture mockup to explain what I’m talking about. I’m using Universal Render Pipeline, 7.1.8.

I can confirm that this C# script to modify the projection matrix to a specific screen-space rectangle still works.
Tested in Unity 2019.3.06f with URP 7.1.8.

This sets the projection matrix to not render geometry outside of the rectangle. You can see this works in both the stats panel and the frame debugger.

Entire screen with no scissor, vs. scissor rectangle set to new Rect(0f, 0f, .25f, .25f); (renders only the bottom left quadrant of the screen).

154606-cameraprojectionmatrix-solved.png

I’ve attached the code as a .txt file, and here’s the original source.

Note that changing the projection matrix does not change the area where your scene is drawn to on the screen. This is achieved by changing the viewport rect of the camera. Instead of the viewport rect you can set the pixelRect in screenspace coordinates instead of normalized coordinates. Once you set a view port rect, it depends on what kind of projection you are looking for. If you don’t change anything at all your view would simply be inside the specified viewport rect just as if that rect is the whole screen.

If you want an off-center projection so that the actual view is based on the whole screen but only seen in the viewport, you need to adjust the projection matrix accordingly. You can refer to my projection matrix crash course over here. Depending on your needs you probably would calculate your left,right,top,bottom, near and far values yourself (don’t forget the aspect ratio). At the end of my matrix crash course I have linked page that explains how to calculate those values based on a fov angle

Hey @Bunny83 thanks for your answer!

To specify any ambiguity, I am not looking for the equivalent of setting the viewport rectangle or pixel rectangle.

I am talking about modifying the camera’s frustum, using the custom projection matrix, so that objects are not physically drawn outside of that rectangle. The closest equivalent I can think of is a hardware scissor rectangle, but I am not sure if Unity supports this.

I did find a thread from 2009 regarding emulating a scissor rect by modifying the projection matrix, but I need to test this script thoroughly.

I also need to set my own oblique projection matrix, and also account for stereoscopic projection in VR, so this could be a bit complex of a solution.

Do you know of any better, more recent, methods to support that emulation of a scissor rect?