Алгоритм удаления скрытой линии для трехмерных сеток? - PullRequest
5 голосов
/ 26 июня 2011

Учитывая произвольную трехмерную сетку, я ищу алгоритм, который выполнял бы удаление скрытой линии в режиме реального времени.Я работаю в контексте OpenGL, что означает, что мы можем воспользоваться Z-буфером.

Я предполагаю, что алгоритм должен включать решение двух следующих проблем:

1) Определение «жестких граней» для последующего рисования с использованием обычных линий OpenGL.Эти «жесткие края» должны соответствовать краям, где угол между двумя соответствующими гранями превышает некоторый порог.

Ради простоты, давайте заявим, что гарантировано, что для каждого ребра определено не более 2 граней.

Расчет "жестких ребер" должен выполняться один раз на сеткуто есть он не связан с точкой обзора.

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

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

Ответы [ 2 ]

4 голосов
/ 26 июня 2011

Здесь происходит несколько вещей.Во-первых, вы хотите нарисовать линии сетки, а во-вторых, вы хотите нарисовать силуэт.Вот общая процедура, чтобы сделать эту работу,

  1. Нарисуйте (используя треугольники) сетку в буфер глубины только путем очистки цветовой маски .

  2. Снова включите цветовую маску, включите front face и измените масштаб / сместите вашу сетку на несколько процентов.Отражение передней грани заставляет вас видеть только внутреннюю часть смещенной сетки, которая обрезается буфером глубины ранее нарисованной сетки.Если вы все сделаете правильно, это должно дать вам аккуратный вид.Вот пример этой техники: http://www.codeproject.com/KB/openGL/Outline_Mode.aspx

  3. Наконец, нарисуйте края сетки (сохраняя буфер глубины нетронутым от предыдущих двух операций) поверх существующей сетки и оболочки.

В результате теперь у вас будут нарисованы все края сетки вместе с красивым силуэтом!

РЕДАКТИРОВАТЬ: после перечитывания вашего поста во второй раз, звучиткак будто вы не хотите рисовать все края, только те, которые находятся на границе с достаточно высокой кривизной.Таким образом, чтобы сделать это, вы можете сделать одно из следующего:

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

  2. В более общем смысле вы также можете приблизить кривизну вашей сетки в пространстве экрана.Это противоположно вычислению так называемой окклюзии окружающего пространства на экране.(Другое аккуратное применение этого метода приведено здесь: http://zigguratvertigo.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/) Как только вы вычислили кривизну вашего объекта из буфера глубины, вы можете отфильтровать линии, только рисуя фрагменты линий, которые встречаются на пикселях с достаточно высокимкривизна.

1 голос
/ 26 июня 2011

Это звучит очень похоже на затенение cel .

Это то, что вы ищете?

Хитрость заключается в удалении тупых краев.Самое сложное в том, чтобы получить правильный порог, он может быть разным для каждого объекта.

Эта статья объясняет больше об алгоритме в целом, это самый быстрый для реализации эффектас помощью пиксельного шейдера

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...