Unity Shaderlab-从屏幕空间到世界空间的转换

时间:2016-10-08 18:19:25

标签: c# matrix unity3d camera shaderlab

我正在制作一个需要世界空间坐标的后处理着色器(统一)。我可以访问某个像素的深度信息,以及该像素的屏幕位置。如何找到该像素对应的世界位置,就像ViewportToWorldPos()函数一样?

2 个答案:

答案 0 :(得分:0)

查看本教程:http://flafla2.github.io/2016/10/01/raymarching.html

基本上:

  • 在屏幕的每个角落存储一个向量,作为常量传递,从摄像机位置到角落。

  • 根据屏幕空间位置或屏幕空间四维的uvs插入向量

  • 将最终位置计算为 cameraPosition + interpolatedVector * depth

答案 1 :(得分:0)

已经三年了!我最近正在研究这个问题,一位老工程师帮助我解决了这个问题。这是代码。

  1. 我们首先需要在脚本中为着色器提供一个摄影机转换矩阵:

    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. 然后,我们需要深度信息来转换片段pos。像这样:

    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;
    }
    

仅此而已。