Z-fighting (сшиванием, плоскостной конфликт) сущность проблемы и методы решения кратко

Лекция 7 мин.



z-fighting (Z-конфликт) , также называемый сшиванием или плоскостным конфликтом , — это явление в 3D-рендеринге , которое возникает, когда два или более примитива находятся на очень похожем расстоянии от камеры. Это приводит к тому, что их значения в z-буфере , отслеживающем глубину, оказываются почти одинаковыми или идентичными. Это означает, что при рендеринге определенного пикселя возникает неоднозначность относительно того, какой из двух примитивов отображается в этом пикселе, поскольку z-буфер не может точно определить, какой из них находится дальше от другого. Если один пиксель однозначно ближе, то менее близкий может быть отброшен. Это особенно характерно для копланарных многоугольников, где две грани занимают практически одно и то же пространство, и ни одна из них не находится перед ними. В результате затронутые пиксели отображаются фрагментами одного или другого многоугольника произвольно, способом, определяемым точностью z-буфера. Это также может меняться при изменении сцены или камеры, в результате чего один многоугольник «выигрывает» z-тест, затем другой и так далее. В итоге получается мерцание и шумное растеризация двух многоугольников, которые «борются» за цвет пикселей экрана. Эта проблема обычно вызвана ограниченной точностью на субпиксельном уровне, ошибками округления при вычислении чисел с плавающей и фиксированной запятой .

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

По мере увеличения расстояния между ближней и дальней плоскостями отсечения , и особенно при выборе ближней плоскости вблизи глаза, возрастает вероятность возникновения z-конфликтов между примитивами. В больших виртуальных средах неизбежно возникает конфликт между необходимостью обеспечения видимости на расстоянии и на переднем плане. Например, в симуляторе космического полета, если далекая галактика нарисована в масштабе, у зрителя не будет достаточной точности для обеспечения видимости любой геометрии кабины на переднем плане (хотя даже численное представление создаст проблемы до рендеринга с использованием z-буфера). Для смягчения этих проблем точность z-буфера смещается в сторону ближней плоскости отсечения, но это не всегда так, и этого недостаточно для устранения всех проблем, связанных с z-конфликтами.

Z-fighting (сшиванием, плоскостной конфликт) сущность проблемы  и методы решения

Демонстрация z-бойца с использованием нескольких цветов и текстур на сером фоне.

Смягчение последствий

Z-fighting (сшиванием, плоскостной конфликт) сущность проблемы  и методы решения
Эффект, наблюдаемый на двух компланарных многоугольниках.Z-конфликт можно уменьшить за счет использования буфера глубины более высокого разрешения , Z-буферизации в некоторых сценариях или просто путем перемещения полигонов дальше друг от друга. [ Z-конфликт, который нельзя полностью устранить таким образом, часто решается с помощью буфера трафарета или путем применения смещения Z-буфера в экранном пространстве после преобразования к одному полигону, которое не влияет на проецируемую форму на экране, но влияет на значение Z-буфера для устранения перекрытия во время интерполяции и сравнения пикселей. В тех случаях, когда Z-конфликт вызван различными путями преобразования в аппаратном обеспечении для одной и той же геометрии (например, в многопроходной схеме рендеринга), его иногда можно решить, запросив у аппаратного обеспечения использование инвариантного преобразования вершин.

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

Z-fighting (сшиванием, плоскостной конфликт) сущность проблемы  и методы решения

Способы решения в игровых движках и системах рендера

1. Самый правильный — убрать совпадение поверхностей

Если объекты действительно должны находиться друг на друге, слегка разнеси их:

Model A: Z = 10.000
Model B: Z = 10.001

Для UI/декалей иногда достаточно очень маленького смещения, например:

transform.position += transform.forward * 0.001f;

Но величина зависит от масштаба сцены.

2. Не делать две копланарные поверхности

Очень частая причина:

████████████  ← Mesh A
████████████  ← Mesh B

Если это, например, земля + плоскость травы, лучше сделать так:

      ████████████ ← трава
------------------ ← земля

То есть дать траве небольшой offset по высоте.

3. Уменьшить Camera Near/Far Clip Plane

Это очень важный момент.

Если камера:

Near = 0.01
Far  = 100000

точность depth buffer распределяется неравномерно, и Z-fighting становится гораздо вероятнее.

Можно пробовать, например:

Near = 0.1
Far  = 1000

или даже:

Near = 0.5
Far  = 500

если игра позволяет.

Особенно важно не ставить чрезмерно маленький Near Clip Plane.

4. Если это декали — использовать Decal Projector

Если ты пытаешься сделать, например:

  • грязь на земле;
  • следы;
  • надписи;
  • повреждения;
  • дополнительные текстуры поверх модели;

не всегда стоит накладывать второй mesh прямо на первый.

В Unity можно использовать Decal Projector / decal-систему соответствующего render pipeline.

5. Для шейдеров — Offset / Polygon Offset

Если ты контролируешь shader, можно использовать depth offset, например концептуально:

Offset -1, -1

Это заставляет поверхность восприниматься как находящаяся немного ближе/дальше при сравнении глубины.

Но это скорее специализированное решение, а не замена исправлению геометрии.

6. Проверь, действительно ли координаты полностью совпадают

Иногда кажется, что:

Position A = (0, 0, 0)
Position B = (0, 0, 0)

но проблема может быть не только в Transform.position.

Могут совпадать именно поверхности mesh после трансформаций, например из-за:

  • одинаковых мешей;
  • одинакового scale;
  • родительских трансформаций;
  • зеркального scale;
  • нескольких Renderer'ов;
  • наложения отдельных материалов.

Внутри одного Terrain раскрашена одну текстуру другой, и на месте перехода начинает мерцать

если мерцание происходит внутри одного Unity Terrain именно при переходе от одной painted texture к другой, то это не обязательно Z-fighting. Более того, в обычной ситуации с двумя слоями Terrain это скорее всего не Z-fighting, потому что Terrain все равно имеет одну геометрическую поверхность, а текстуры смешиваются шейдером.

Что происходит

Допустим, на одном Terrain есть раскаска :

  • травы
  • земли
  • камня

Unity не кладет три поверхности друг на друга. У него примерно такая схема:

              ОДНА поверхность Terrain
        ───────────────────────────────
           ↑       ↑       ↑
         трава    земля   камень

        Texture 1 ─┐
        Texture 2 ─┼─→ смешивание → итоговый цвет
        Texture 3 ─┘

Поэтому если на границе трава ↔ земля появляется мерцание, рябь, белые/темные пиксели или поверхность будто «перескакивает», надо искать причину в другом.

Наиболее вероятные причины

1. Texture aliasing / shimmering — наиболее вероятный вариант

Если текстура имеет мелкие детали:

▒▒▒▒▒░░▒▒░░▒▒▒▒░░
░▒▒▒░░▒▒▒▒░░▒▒▒░░

и игрок смотрит на Terrain под острым углом или издалека, отдельные пиксели текстуры начинают быстро меняться между mip-уровнями.

Получается:

Кадр 1 → ░▒░▒░▒
Кадр 2 → ▒░▒░▒░
Кадр 3 → ░▒░▒░▒

И глаз воспринимает это как мерцание.

Это особенно заметно у:

  • камней;
  • травы;
  • гравия;
  • мелких пятен;
  • очень контрастных текстур;
  • normal map;
  • detail map.

2. Проблема с mipmaps

Очень частый источник мерцания.

Если текстура имеет неправильные или отсутствующие mipmaps, при удалении камеры она может выглядеть нестабильно.

Проверь настройки текстуры в Inspector:

Texture Import Settings → Generate Mip Maps

Для обычных Terrain-текстур mipmaps обычно должны быть включены.

3. Слишком резкий переход между Terrain Layers

На границе используются несколько текстур одновременно.

Если сами текстуры сильно отличаются по детализации/контрасту, граница может визуально «шуметь».

Попробуйте увеличить Brush Opacity не обязательно — важнее сделать переход более широким и плавным.

4. Normal Map может давать ощущение мерцания

Это очень распространенная причина, особенно если цветовая текстура выглядит нормально, но поверхность все равно «блестит» или рябит.

Например:

Albedo → нормально
Normal Map → X слишком сильная детализация
                     ↓
               мерцание света

Попробуй временно убрать Normal Map у проблемного Terrain Layer.

Если мерцание исчезло — проблема практически найдена.

5. Очень контрастные текстуры

Например:

Плохо:

белый камень █████
черные пятна █████

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

Лучше:

текстура с более равномерной частотой деталей и меньшим экстремальным контрастом.

А вот когда это действительно Z-fighting

Если у тебя два Terrain или две поверхности Terrain находятся друг над другом, тогда да:

Terrain A
────────────────────

Terrain B
────────────────────

И вот здесь уже настоящий Z-fighting.

Например, особенно стоит проверить:

  • случайно дублированный Terrain;
  • два Terrain Tile, которые перекрываются;
  • Terrain + Plane;
  • Terrain + другой mesh;
  • кусок меша, лежащий практически на поверхности Terrain.

Как быстро определить причину

Сделайте такой тест:

Тест №1

У проблемной текстуры временно уберите Normal Map.

Мерцание исчезло → проблема в Normal Map/освещении.

Тест №2

Заменитепроблемную текстуру на простую однотонную.

Исчезло → про блема в самой текстуре, mipmaps или aliasing.

Тест №3

Приблизьте камеру.

Если:

далеко → мерцает
близко → нормально

то очень вероятны mipmapping / texture aliasing / filtering.

Тест №4

Отключите второй Terrain Layer.

Если мерцание исчезает именно при его отключении — исследуй текстуру, normal map и параметры Terrain Layer, а не Z-buffer.

Тест №5

Включите Scene View и посмотри геометрию.

Если обнаружится:

Terrain
   +
другая поверхность

тогда уже проверяй Z-fighting.

Способы диагности проблемы

проверка в таком порядке:

1. Normal Map проблемного Terrain Layer
↓
2. Mip Maps текстуры
↓
3. Texture Filtering / Anisotropic Filtering
↓
4. Слишком мелкий/контрастный рисунок текстуры
↓
5. Terrain Layer / shader
↓
6. И только потом Z-fighting

То есть не стоит сразу лечить это через Near/Far Clip Plane. Если у тебя действительно одна поверхность Terrain, изменение Near/Far может вообще ничего не дать.

создано: 2026-09-03
обновлено: 2026-09-29
1



Помог ли вам этот ответ?
Нажмите оценку и напишите коротко почему. Так мы сможем сделать следующие ответы точнее и полезнее.
Насколько вы довольны ответом?
Ваш отзыв напрямую влияет на качество следующих подсказок и ответов.


Поделиться:
Пожаловаться

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выполнения задания
  • Возможно применение функции гаранта на сделку
  • Приоритетная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можете продать (как исполнитель) или купить (как заказчик) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно применение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей

Комментарии

Оставить комментарий

Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

Лекции и учебник по "Компьютерная графика"

Термины: Компьютерная графика