Решения Z-борьбы в глубине тестирования в OpenGL - как они работают?
Описание
У меня были серьезные проблемы с Z-Fighting в OpenGL, и я потратил довольно много времени на поиск решений этой проблемы. Некоторые из тех, что я нашел, и я понимаю, и мне не понравилось:
Перемещение полигонов друг от друга (например, glPolygonOffset в OpenGL)Разделение сцены по координате Z и рисование частей сцены с отдельными чистыми z-буферами.Те, которые я не понимаю:
Использование проекционной матрицыhttps://software.intel.com/en-us/articles/alternatives-to-using-z-bias-to-fix-z-fighting-issuesИспользование «логарифмических буферов глубины»http://outerra.blogspot.com/2012/11/maximizing-depth-buffer-range-and.htmlЯ реализовал второй в моей программе, просто поместив его в вершинный шейдер шара (он боролся с землей):
float C = 1.0;
float far = 2000.0;
gl_Position = u_projView * a_position;
gl_Position.z = 2.0*log(gl_Position.w*C + 1.0)/log(far*C + 1.0) - 1.0;
gl_Position.z *= gl_Position.w;
и это сработало!
Актуальные вопросыМожет кто-нибудь объяснить мне, как изменение координаты Z вершины в вершинном шейдере решило проблему БЕЗ перемещения вершины ко мне? (сцена выглядит так же для человеческого глаза). Как это изменило распределение значений глубины z? Я предполагаю, что мне не хватает некоторых знаний о рендеринге конвейера.Может ли кто-нибудь объяснить мне, как мы можем использоватьПроекционная матрица решить проблему ? И как это работает?Существуют ли другие аналогичные эффективные способы решения проблемы z-борьбы?Спасибо!