How do you get the world position from the screen position in a URP shader graph used in a ScriptableRenderPass?

I’m using a shader graph in the Universal Shader Pipeline (URP) to do some post-processing in a ScriptableRenderPass. How do I get the world coordinates of the screen position?

I have tried using the View Direction node, set to World:

And I have tried the Screen Position node:

Neither seems to be working because the colors change as I move the camera around, but I would expect the color to stay the same since the world position of the GameObject is not changing. Any suggestions?

Something along the lines of this should work;

You will however probably need to provide the inverse-projection matrix yourself for two reasons;

  1. Shader graph is barely functional at best, and currently just using the inverse-projection matrix will throw errors.

  2. The matrices shader graph provides would probably already be API converted, meaning you would need to manually handle platform differences. As such, if you just pass in the raw inverse-projection matrix from your camera (Unity uses OpenGL convention) this should just work.

    //One way to set this up for the scene globally
    //You don’t need this script on every object, just one place in the scene will do (some kind of singleton game-manager object, that kind of thing)

    public class MatrixSetup : MonoBehaviour
    private void OnEnable ()
    Camera.onPreCull += SetupMatrices;

    private void OnDisable ()
        Camera.onPreCull -= SetupMatrices;
    private void SetupMatrices (Camera cam)
        //Just make sure you have a custom matrix property on your material called _InvProjectionMatrix and use that instead
        Shader.SetGlobalMatrix ("_InvProjectionMatrix", cam.projectionMatrix.inverse);