Выборка буфера глубины и нормализация до [0,1] (DirectX)

Я пытаюсь визуализировать (в целях отладки) глубину сцены на текстурированном квадроцикле (я хочу отобразить глубину водоема на поверхности воды). Итак, что я делаю, это визуализирую сцену с точки зрения камеры в буфере глубины, а затем привязываю тот же буфер глубины, что и ресурс шейдера, к шейдеру воды. Но когда я пробую текстуру, я всегда получаю полностью белую текстуру. Я использовал pow(value, 100.0), и у меня есть небольшая вариация, которая правильно соответствует глубине ландшафта под водой, поэтому я должен предположить, что некоторые значения есть, но они находятся в небольшом диапазоне около 1,00. Поэтому я попытался нормализовать значения, инвертировав перспективное преобразование для z (из пространства отсечения обратно в пространство для глаз) с помощью следующего уравнения:

float linearDepth = near * far / (far - depth * (far - near));

но опять же абсолютно белый. Формула мне кажется правильной (я нашел ее в книге Фрэнка Луны, и даже если я вычисляю матрицу проекции самостоятельно, я ее получаю). Дальняя и ближняя плоскости находятся в диапазоне 0,1 300,0, но даже игра с этими значениями никуда меня не приведет.

Все это потому, что я хочу реализовать мягкие края на своей воде и мне нужны значения глубины, но я хочу визуализировать их раньше, чтобы знать, что делаю это правильно.


person Luca    schedule 07.05.2018    source источник


Ответы (1)


Вы правы, что со стандартной матрицей проекции распределение значений глубины будет очень близко к значению 1 (только очень близкие объекты будут показывать видимую разницу). Если дальняя плоскость действительно, очень близко, вы не увидите значений заметно ниже 1. Это также усугубляется тем фактом, что человеческий глаз не видит небольших дельт в ярких цветах почти так же хорошо, как между темными цветами (так что вы меньше видите изменения).

Вы определенно на правильном пути с линеаризацией буфера глубины. Раньше у меня это работало (в OpenGL, поэтому YMMV) с чем-то вроде следующего:

float lineardepth = (2.0f * near) / (far + near - depth * (far - near));

Это должно быть очень похоже на то, что работает и в D3D.

person Varrak    schedule 14.05.2018
comment
Я обнаружил, что, используя свою формулу преобразования, я получаю координату z в пространстве глаза / камеры, поэтому она варьируется от ближнего до дальнего. Если я вычитаю значение «близко» и делю его на («далеко-близко»), я получаю линейное представление значений глубины. - person Luca; 15.05.2018