1

I'm making a post-processing shader (in unity) that requires world-space coordinates. I have access to the depth information of a certain pixel, as well as the onscreen location of that pixel. How can I find the world position that that pixel corresponds to, much like the function ViewportToWorldPos()?

HalpPlz
  • 691
  • 4
  • 11
  • Check out the 'Slices via World Space Position' example here (scroll down): https://docs.unity3d.com/Manual/SL-SurfaceShaderExamples.html – Absinthe Oct 08 '16 at 18:27
  • This has nothing to do with what I want. I'm using a post-processing shader. – HalpPlz Oct 08 '16 at 18:31
  • OK try here: http://www.alanzucconi.com/2015/07/08/screen-shaders-and-postprocessing-effects-in-unity3d/ You know about search engines, right? – Absinthe Oct 08 '16 at 18:38
  • I do know about search engines. This article isn't really helpful to me, as I already know how to do post-processing shaders in general. I need help with this specific issue. – HalpPlz Oct 08 '16 at 18:41

2 Answers2

1

It's been three years! I was working on this recently, and an older engineer help me solved the problem. Here is the code.

  1. We need to firstly give a camera transform matrix to the shader in script:

    void OnRenderImage(RenderTexture src, RenderTexture dst)
    {
        Camera curruntCamera = Camera.main;
        Matrix4x4 matrixCameraToWorld = currentCamera.cameraToWorldMatrix;
        Matrix4x4 matrixProjectionInverse = GL.GetGPUProjectionMatrix(currentCamera.projectionMatrix, false).inverse;
        Matrix4x4 matrixHClipToWorld = matrixCameraToWorld * matrixProjectionInverse;
    
        Shader.SetGlobalMatrix("_MatrixHClipToWorld", matrixHClipToWorld);
        Graphics.Blit(src, dst, _material);
    }
    
  2. Then we need the depth information to transform the clip pos. Like this:

    inline half3 TransformUVToWorldPos(half2 uv)
    {
        half depth = tex2D(_CameraDepthTexture, uv).r;
        #ifndef SHADER_API_GLCORE
            half4 positionCS = half4(uv * 2 - 1, depth, 1) * LinearEyeDepth(depth);
        #else
            half4 positionCS = half4(uv * 2 - 1, depth * 2 - 1, 1) * LinearEyeDepth(depth);
        #endif
        return mul(_MatrixHClipToWorld, positionCS).xyz;
    }
    

That's all.

RobC
  • 22,977
  • 20
  • 73
  • 80
yuans
  • 11
  • 2
0

have a look at this tutorial: http://flafla2.github.io/2016/10/01/raymarching.html

essentially:

  • store one vector per corner of the screen, passed as constants, that goes from the camera position to said corner.

  • interpolate the vectors based on the screen space position, or the uvs of your screenspace quad

  • compute final position as cameraPosition + interpolatedVector * depth

Brice V.
  • 861
  • 4
  • 7