Z-fighting , также называемый сшиванием или planefighting , — это явление в 3D-рендеринге , которое происходит, когда два или более примитивов находятся на очень близких расстояниях от камеры. Это приводит к тому, что они имеют почти одинаковые или близкие значения в z-буфере , который отслеживает глубину. Это означает, что при рендеринге определенного пикселя неоднозначно, какой из двух примитивов отрисовывается в этом пикселе, поскольку z-буфер не может точно различить, какой из них находится дальше от другого. [1] Если бы один пиксель был однозначно ближе, то менее близкий можно было бы отбросить. Это особенно распространено с копланарными полигонами, где две грани занимают по сути одно и то же пространство, и ни одна из них не находится впереди. В результате затронутые пиксели рендерятся с фрагментами из одного или другого полигона произвольно, способом, определяемым точностью z-буфера. Это также может меняться при изменении сцены или камеры, в результате чего один полигон «выигрывает» z-тест, затем другой и так далее. Общий эффект — мерцающая, шумная растеризация двух полигонов, которые «борются» за цвет пикселей экрана. Эта проблема обычно вызвана ограниченной точностью субпикселя, ошибками округления с плавающей и фиксированной точкой .
Чем выше точность z-буфера, тем меньше вероятность, что возникнет z-борьба. Но для копланарных полигонов проблема неизбежна, если не предпринять корректирующие действия.
По мере увеличения расстояния между ближней и дальней плоскостями отсечения , и в частности, ближняя плоскость выбирается около глаза, тем больше вероятность возникновения z-борьбы между примитивами. В больших виртуальных средах неизбежно возникает внутренний конфликт между необходимостью разрешать видимость на расстоянии и на переднем плане, так, например, в симуляторе космического полета, если далекая галактика нарисована в масштабе, у наблюдателя не будет точности, чтобы разрешить видимость на любой геометрии кабины на переднем плане (хотя даже численное представление будет представлять проблемы до рендеринга с z-буферизацией). Чтобы смягчить эти проблемы, точность z-буфера взвешивается в сторону ближней плоскости отсечения, но это касается не всех схем видимости, и этого недостаточно для устранения всех проблем z-борьбы.
Z-борьба может быть уменьшена за счет использования буфера глубины с более высоким разрешением , z-буферизации в некоторых сценариях или простого перемещения полигонов дальше друг от друга. [2] Z-борьба, которую невозможно полностью устранить таким образом, часто решается с помощью буфера трафарета или путем применения смещения z-буфера экранного пространства после преобразования к одному полигону, которое не влияет на проецируемую форму на экране, но влияет на значение z-буфера для устранения перекрытия во время интерполяции и сравнения пикселей. Когда z-борьба вызвана различными путями преобразования в оборудовании для одной и той же геометрии (например, в многопроходной схеме рендеринга), ее иногда можно решить, запросив, чтобы оборудование использовало инвариантное преобразование вершин.
Z-fighting, вызванный недостаточной точностью буфера глубины, можно устранить, просто уменьшив видимое расстояние в мире. Это уменьшает расстояние между ближней и дальней плоскостями и решает проблему точности. Однако в некоторых виртуальных средах, где видимость на большом расстоянии имеет важное значение или где ограниченная видимость была бы невероятной, например, в космическом симуляторе или симуляторе полета, это невозможно. В этих случаях существуют альтернативные методы. Один из таких методов заключается в «симуляции» расстояния до объектов, находящихся далеко от пользователя, без фактического изменения их положения. Например, если максимальное безопасное расстояние обзора (за пределами которого происходит z-fighting) составляет 10 000 единиц, а объект, который нужно отрисовать, находится на расстоянии 15 000 единиц, этот объект можно было бы отрисовать на 10 000 единиц, но его можно было бы масштабировать пропорционально расстоянию, на которое он был перемещен. Таким образом, объект, масштаб которого был уменьшен вдвое, будет выглядеть так, будто он находится в два раза дальше, чем на самом деле. Если это делается только для объектов, которые уже близки к максимальному расстоянию обзора или находятся на нем, а объекты, близкие к пользователю, отображаются нормально, этот метод не должен быть заметен. Другой метод, который используется для уменьшения или полного устранения Z-борьбы, — это переключение на логарифмический Z-буфер, реверсирование Z. Этот метод используется в игре Grand Theft Auto V. Из-за способа кодирования числа с плавающей точкой имеют гораздо большую точность, когда они ближе к 0. Здесь реверсирование Z приводит к большей точности при сохранении глубины очень удаленных объектов, следовательно, значительно уменьшая Z-борьбу. [3]