Unity Shaderlab- трансформация из экранного пространства в мировое пространство
Я делаю шейдер постобработки (в единстве), который требует координат мирового пространства. У меня есть доступ к информации о глубине определенного пикселя, а также к экранному расположению этого пикселя. Как я могу найти положение в мире, которому соответствует этот пиксель, так же, как функция ViewportToWorldPos()?
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); }
Затем нам понадобится информация о глубине, чтобы преобразовать клип 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; }
Вот и все.
Взгляните на этот учебник: http://flafla2.github.io/2016/10/01/raymarching.html
по существу:
сохранить один вектор на угол экрана, передаваемый в виде констант, который идет от положения камеры к указанному углу.
интерполируйте векторы в зависимости от положения на экране или от величины квадрата пространства экрана
вычислить конечную позицию как cameraPosition + interpolatedVector * глубина