Если вы делаете перспективное изображение и ваша модель имеет неявные пересечения, то, если вы используете «линейный Z», эти пересечения появятся в неправильных местах.
Например, рассмотрим простую плоскость заземления с линией телефонных столбов, уходящих вдаль, которые пронзают землю (и продолжают движение ниже). Неявные пересечения будут определяться интерполированными значениями глубины. Если их не интерполировать 1/Z
, тогда, когда спроецированные вершины были вычислены с перспективой, изображение будет выглядеть некорректно.
Я извиняюсь за неэстетичное качество следующих иллюстраций, но я сделал их еще в 97 году.
Первое изображение показывает необходимый эффект рендеринга. (Обратите внимание, что синие "пилоны" проходят довольно большое расстояние под земной плоскостью, поэтому они обрезаны внизу изображений)
Это второе изображение показывает результат использования невзаимного буфера глубины: (Извинения за изменение масштаба - они были скопированы из старого документа MS Word, и я не знаю, что случилось с масштабированием.)
Как видите, результаты неверны.
С другой стороны, вы действительно хотите линейное представление Z? Если вы визуализируете перспективу, конечно, вам нужно больше точности ближе к камере, чем на расстоянии?
Re ваш последующий комментарий:
«Если они не интерполируются с 1 / Z», что я не понимаю. Что это за интерполяция?
Первое, на что следует обратить внимание, это то, что при стандартной перспективной проекции прямые линии в мировом пространстве остаются прямыми линиями в перспективном пространстве. Расстояния / длины, однако, не сохраняются.
Для простоты предположим, что для проекции вершин используется тривиальное перспективное преобразование, т.е.
ИксSс т е е пзнак равноИксWо г л гZWо г л г
YSс т е е пзнак равноYWо г л гZWо г л г
Мы также должны вычислить обратную глубину экранного пространства, напримерZSс т е е пзнак равно1ZWо г л г
но для линейного Z в буфере глубины мне потребуется что-то вроде: ZSс т е е п= s c a l e ∗ZWо г лг
(Здесь можно предположить, что масштаб = 1)
Давайте предположим, что у нас есть линия с конечными точками мирового пространства⎡⎣⎢001⎤⎦⎥а н д⎡⎣⎢200010⎤⎦⎥
С перспективным отображением этих карт на экран координат пространства
⎡⎣⎢001⎤⎦⎥а н д⎡⎣⎢2000,1⎤⎦⎥
Система / оборудование рендеринга будет линейно интерполировать пространство экрана z, поэтому в точке пути 1/2 линии, как это отображается на экране, то есть в пикселе (10, 0), мы получили бы проецируемое (обратное) значение Z значение 0,55, что соответствует значению Z мирового пространства ~ 1,818. Учитывая начальные и конечные значения Z, это составляет около 20% по длине линии.
Если бы вместо этого мы попытались интерполировать, используя исходные значения Z, мы бы получили Z, соответствующее значению мирового пространства 5,5. Пока ничто не пересекается, вы можете быть в порядке (я не думал об этом слишком тщательно), но все с неявными пересечениями будет неправильным.
Что я не упомянул, так это то, что после того, как вы введете перспективное правильное текстурирование (или даже перспективное правильное затенение), вы должны выполнить интерполяцию по пикселям 1 / w и, кроме того, также вычислить, по пикселю, обратную величину этого интерполированного значения.
far / z
, которое является стандартным, не имеет смысла. Это дает буфер глубины, который становится более линейным, чем ближе две плоскости отсечения друг к другу. Это похоже на сочетание двух понятий: экранно-линейная Z и отображение буфера непостоянной глубины для взлома производительности.(x, y, z) / w
для фрагмента, но, по-видимому, вместо этого мы имеем дело с линейно-интерполированной версией(x/w, y/w, z/w)
? Это не кажется мне разумным в 2018 году, но было бы неплохо знать, если мы все равно будем жить с этим взломом!Использование Z / W для буфера глубины идет глубже, чем просто отсечение по ближним и дальним плоскостям. Как намекал Саймон, это связано с интерполяцией между вершинами треугольника во время растеризации.
Z / W - это уникальная опция, которая позволяет правильно рассчитывать значения глубины NDC для точек внутри треугольника, просто линейно интерполируя значения глубины NDC из вершин в пространстве экрана . В принципе, мы могли бы использовать любую функцию, которая нам нравится, чтобы отобразить пространство камеры Z в значение буфера глубины, но любой другой выбор, кроме Z / W, потребовал бы более сложной математики для каждого пикселя, которая была бы медленнее и труднее встроить аппаратное обеспечение.
Обратите внимание, что если вы используете буфер линейной глубины, то, конечно, линейная интерполяция значений глубины будет правильной в мировом пространстве ... но не, вообще, в экранном пространстве! И именно растровое пространство имеет значение для растеризации, поскольку нам нужно иметь возможность генерировать правильные в перспективе значения глубины (и другие значения атрибутов, например, UV) для каждого центра пикселя или другой точки выборки в пределах границ экранного пространства растровый треугольник.
источник