Как правильно отображать совпадающие полигоны в OpenGL (ES)

Я понимаю, что, установив функцию глубины в OpenGL ES, можно контролировать, как перекрывающиеся геометрические объекты отображаются в 3D-сцене. Я использую gl.depthFunc(gl.LEQUAL) (webgl) в своем коде.

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

введите здесь описание изображения

Как я могу это исправить? Я пробовал разные значения depthFunc, но ни одно из них не решает эту проблему. Я бы хотел, чтобы совпадающие полигоны были одного цвета, неважно какого.


person Jayesh    schedule 20.10.2011    source источник


Ответы (4)


Это называется z-fighting и связано с визуализацией двух объектов на одной глубине. , но ошибки округления (и точность буфера глубины) иногда появляются одна перед другой. Одним из доступных вам решений является использование функции glPolygonOffset:

http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPolygonOffset.xml

Вы можете увидеть пример его использования в нижней части этой страницы:

http://www.glprogramming.com/red/chapter06.html

person River    schedule 20.10.2011

То, что вы испытываете, называется борьбой с Z, и, к сожалению, против этого нет окончательного решения. Что происходит, так это то, что из-за ограниченной точности буфера глубины возникают ошибки округления, и любой из примитивов «выигрывает» операцию проверки глубины. Изменение функции глубины просто переключит цвета в боевой схеме, но не удалит ее.

Один из способов избавиться от смещения Z — использовать смещение полигона http://www.opengl.org/wiki/Basics_Of_Polygon_Offset

К сожалению, смещение полигонов создает свою долю проблем.

person datenwolf    schedule 20.10.2011

Попробуйте изменить z-near так, чтобы он был дальше от нуля в вашем вызове gluPerspective:

void gluPerspective(
    GLdouble    fovy,
    GLdouble    aspect,
    GLdouble    zNear,
    GLdouble    zFar);

С этого веб-сайта: http://www.opengl.org/resources/faq/technical/depthbuffer.htm

Похоже, буферизация глубины работает, но полигоны, кажется, просачиваются через полигоны, которые находятся перед ними. Что происходит?

Возможно, вы настроили плоскости отсечения zNear и zFar таким образом, что это сильно ограничивает точность буфера глубины. Как правило, это вызвано тем, что значение плоскости отсечения zNear слишком близко к 0,0. Поскольку плоскость отсечения zNear устанавливается все ближе к 0,0, эффективная точность буфера глубины резко снижается. Перемещение плоскости отсечения zFar дальше от глаза всегда оказывает негативное влияние на точность буфера глубины, но не так сильно, как перемещение плоскости отсечения zNear.

person Andrew Garrison    schedule 20.10.2011
comment
Хотя уменьшение диапазона глубины координат глаза, безусловно, помогает сохранять близкие, параллельные, но не пересекающиеся полигоны, это не поможет для копланарных полигонов, что, по-видимому, пытается сделать OP. - person datenwolf; 20.10.2011
comment
Ах, хороший момент. Теперь я разрываюсь, оставить ли этот ответ здесь. - person Andrew Garrison; 20.10.2011
comment
Оставьте это, потому что это хороший совет, относящийся к теме, и у нас также есть комментарии, чтобы объяснить, почему это не правильный ответ для этого конкретного сценария. Никакого вреда, и мы все чему-то учимся. :) - person Toji; 21.10.2011
comment
Я так рад, что вы оставили это здесь, так как это только что помогло мне решить мою собственную проблему, которая касается ключевых слов этого вопроса. - person Josh Peak; 14.08.2015

Попробуйте поиграть с glPolygonOffset(factor, units). Эта страница может помочь.

person Toomai    schedule 20.10.2011