1

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

4

2 回答 2

1

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

  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. 然后我们需要深度信息来转换剪辑位置。像这样:

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

就这样。

于 2019-10-29T02:46:27.847 回答
0

看看这个教程: http: //flafla2.github.io/2016/10/01/raymarching.html

本质上:

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

  • 根据屏幕空间位置或屏幕空间四边形的 uv 插入向量

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

于 2017-12-22T10:17:47.957 回答