URP RenderGraph RenderPass - Render from Different Position/View Matrix

I’ve tried several different ways of rendering a URP render graph RasterRenderPass with an overridden camera position, but none seem to work correctly. What I’ve tried:

  • Calculating the new view matrix and applying it using RasterGraphContext.cmd.SetViewProjectionMatrices(viewMat, projMat)
  • Setting builder.AllowGlobalStateModification to true and setting the _WorldSpaceCameraPos global shader variable using RasterGraphContext.cmd.SetGlobalVector
  • Setting the UNITY_MATRIX_V global shader variable using RasterGraphContext.cmd.SetGlobalMatrix
  • Trying the previous two things using Shader.SetGlobalVector/Matrix
  • Using passData to pass a reference to the camera and setting its transform’s position directly

Any help or a point in the right direction would be greatly appreciated. Not sure if it’s relevant, but I’m also using a RendererList to draw objects in this pass (based on the RendererListRenderFeature example in the URP render graph samples.) Also, I ultimately want the ability to set other camera properties as well like FOV and its rotation maybe.

I can see from the C# reference for the URP RenderObjectsPass that RenderingUtils.SetViewAndProjectionMatrices is used to override the camera’s matrices. When I try this, the code doesn’t even compile because it wont accept a RasterCommandBuffer as an argument.

If these are internal methods being used to do basic things like change the camera’s view and projection matrices, what is the intended workflow for someone someone scripting a render pass? I’m finding this information difficult to locate.

Hi, maybe you can try using an Unsafe Pass as a temporary alternative.

You can get the native command buffer in an Unsafe Pass:

CommandBuffer cmd = CommandBufferHelpers.GetNativeCommandBuffer(UnsafeCommandBuffer context.cmd);

I suggest asking them directly in the render graph thread or submit a bug report.

Hey @owennnnnnnnn, you are on the right track. I think reproducing what is done in the URP RenderObjectsPass is a good idea. I can see that the overload of SetViewAndProjectMatrices taking a raster command buffer as a parameter is currently internal, making your journey difficult. I will double check but it should be public.

For now, as @wwWwwwW1 suggested, you can use an unsafe pass and get the native command buffer to call SetViewAndProjectionMatrices within your pass.

Oh man… I was struggling to work around this for a stencil portal pass (based on RenderObjectsPass) in 2023.3 beta. I remember trying a dozen things including writing to CameraData before and after cmd.DrawRendererList(), but nothing worked and I had/have no idea how to debug these things. Hopefully exposing this more proper way of setting matrices will make it closer to what I’m currently doing with the Camera component and potentially fix the render pass… Thanks for looking into it!

Hello everyone,

We just landed the small change making this API public. It will be available in 6000.0.30f1. Thanks a lot for the feedback, happy coding!

        /// <summary>
        /// Set view and projection matrices.
        /// This function will set <c>UNITY_MATRIX_V</c>, <c>UNITY_MATRIX_P</c>, <c>UNITY_MATRIX_VP</c> to given view and projection matrices.
        /// If <c>setInverseMatrices</c> is set to true this function will also set <c>UNITY_MATRIX_I_V</c> and <c>UNITY_MATRIX_I_VP</c>.
        /// </summary>
        /// <param name="cmd">RasterCommandBuffer to submit data to GPU.</param>
        /// <param name="viewMatrix">View matrix to be set.</param>
        /// <param name="projectionMatrix">Projection matrix to be set.</param>
        /// <param name="setInverseMatrices">Set this to true if you also need to set inverse camera matrices.</param>        
        public static void SetViewAndProjectionMatrices(RasterCommandBuffer cmd, Matrix4x4 viewMatrix, Matrix4x4 projectionMatrix, bool setInverseMatrices)