2015-05-24 2 views
2

Я использую TriangleList для вывода моих примитивов. В большинстве случаев мне нужно рисовать прямоугольники, треугольники, круги. Время от времени мне нужно рисовать очень тонкие треугольники (например, ширина = 2px). Я думал, что она должна выглядеть как линия (почти линия), но это выглядит как отдельные точки :)OpenGL: рисование очень тонких треугольников с поворотом TriangleList в очки

Следующая картинка показывает, что я говорю о:

enter image description here

Первая картина на левой стороне показывает, как рисовать прямоугольник (против часовой стрелки, в верхнем правом углу). И тогда вы можете увидеть «ширину» прямоугольника, который я называю «dx».

Как избежать такого поведения? Я бы это выглядел как прямая (почти прямая) линия, а не как точки :)

+5

Если у вас, скажем, (замкнутый) твердый или сетка из треугольников, вы должны были бы эти пиксели, чтобы избежать «трещины». Существуют определенные правила растеризации, которые определяют, какие пиксели «находятся», с соглашениями об отключении таймаута (полуоткрытый интервал), чтобы гарантировать, что треугольники, разделяющие край, не имеют избыточности. Вы можете улучшить внешний вид с помощью [мультисэмплинг] (https://www.opengl.org/wiki/Multisampling) или какой-либо другой метод сглаживания. –

+3

Чтобы продолжить комментарий @BrettHale, если вы добавите четвертую вершину, чтобы четыре из них сформировали квадрат, состоящий из двух треугольников (34 были параллельными и имели такую ​​же длину dx, что и 12), правила растрирования сделает второй треугольник заполнить пробелы, оставшиеся растеризацией треугольника 123. – datenwolf

+0

@ datenwolf Я попытался нарисовать два треугольника вручную, используя 6 вершин (3 вершины для каждого треугольника), и результат почти такой же. Это исчезает почти на всех :) – JavaRunner

ответ

0

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

  Gl.glShadeModel(Gl.GL_SMOOTH); 
      Gl.glEnable(Gl.GL_LINE_SMOOTH); 
      Gl.glEnable(Gl.GL_BLEND); 
      Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA); 
      Gl.glHint(Gl.GL_LINE_SMOOTH_HINT, Gl.GL_DONT_CARE); 

перед нанесением линии, так что вы получите линии, когда ваш треугольник очень мал ...

+0

Вы не избежите артефактов таким образом, потому что это проблема сглаживания. –

1

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

Попробуйте включить мультисэмплинг. Большинство библиотек окон GL поддерживают многосэмплированный обратный буфер. Вы также можете включить его в настройках графического драйвера.

4

Как @BrettHale упоминает, это проблема псевдонимов. Например,

enter image description here

Без супер/мультисэмплинга треугольник покрывает только центральную часть нижнего правого пиксела, и только он получит цвет. Реальные пиксели имеют площадь и в идеальной ситуации получат часть цвета, равную площади, покрытой. Методы «сглаживания» уменьшают aliasing эффекты, вызванные не интегрированием цвета по пикселям.

enter image description here

Как это выглядит правильно, не будучи невероятно медленно, трудно. OpenGL предоставляет GL_POLYGON_SMOOTH, который консервативно растеризует треугольники и рисует правильные проценты цвета для каждого пикселя с использованием смешивания. Это хорошо работает, пока у вас нет перекрывающихся треугольников, и вы попадаете на проблему сортировки прозрачности, где требуется order-independent transparency. Простое и более грубое решение состоит в том, чтобы визуализировать гораздо большую текстуру, а затем уменьшать размер. Это, по сути, то, что делает суперсэмплинг, за исключением того, что образцы могут быть «анизотропными» (нерегулярными), что дает более приятный результат. Методы мультисэмплирования являются адаптивными и немного более эффективными, например. суперсэмплы пикселей только на краях треугольника. Это довольно просто: set this up with OpenGL.

Однако, когда область треугольника приближается к нулю, область будет также и полностью исчезнет даже при сглаживании (хотя будет исчезать, а не становиться пиксельной). Хотя это и не является физически корректным, вы можете вместо трех минимального треугольника шириной в 1 пиксель, чтобы получить нужные строки, даже если это очень тонкий треугольник. Здесь может быть интересен ваш собственный conservative rasterization.

enter image description here