Оказывается, я забыл отменить окончательное значение Z, чтобы получить положительное расстояние перед ближней плоскостью (камера OpenGL смотрит вниз -Z). Для дальнейшего использования код GLSL для определения расстояния перед ближней плоскостью:
float depth = /* sampled from depth texture as in the original question */ ;
vec4 screenPos = vec4(tcScreen.x, tcScreen.y, depth, 1.0) * 2.0 - 1.0;
vec4 viewPosition = projectionMatrixInverse * screenPos;
float z = -(viewPosition.z / viewPosition.w);
Если вы хотите вместо этого использовать положение в мировом пространстве (как это использовал SuperPro), то это можно найти, комбинируя матрицы вида и проекции и затем используя обратную матрицу, а не просто используя обратную матрицу проекции.
Поскольку необходимы только компоненты Z и W viewPosition
, вышеуказанный GLSL для вычисления viewPosition
может быть несколько упрощен. Достаточно двух точечных произведений вместо полного умножения матрицы, и нет необходимости подавать полную матрицу обратной проекции в шейдер, так как нужны только две нижние строки:
vec2 viewPositionZW = vec2(
dot(projectionMatrixInverseRow2, screenPos),
dot(projectionMatrixInverseRow3, screenPos)
);
float z = -(viewPositionZW.x / viewPositionZW.y);
Производительность при этом немного хуже, чем при использовании ближнего и дальнего расстояний, предположительно из-за продуктов с дополнительными точками, я получил снижение на ~ 5%. Математика ближнего и дальнего расстояния также может быть оптимизирована путем ввода (zNear * zFar)
и (zFar - zNear)
в качестве констант, но я не увидел какого-либо ощутимого улучшения при этом.
Интересно, что когда вы комбинируете вышеупомянутое с матрицей проекции, которая использует косое усечение усеченного контура, я не могу получить ничего разумного из этого, но я получаю разумный вывод при использовании уравнения ближнего и дальнего расстояния с той же матрицей проекции хотя это может показаться некоторым искажением значений глубины (хотя это может быть связано с потерей точности глубины, присущей косому усечению усеченного усеченного конуса). Если кто-то может пролить свет на то, что здесь происходит математически, я был бы признателен, хотя, возможно, это должно быть в другом вопросе.