Я работаю над настройкой активного контура в своем 3d движке, эффектом выделения для выбранных 3d персонажей или пейзажей на экране. После работы с буфером трафарета и получения некоторых неудовлетворительных результатов (проблемы с вогнутыми формами, толщиной контура из-за расстояния от камеры и несоответствия между моим рабочим столом и ноутбуком) я переключился на обнаружение краев и выборку из буфера кадров и получил схему очень доволен.
Однако я не могу скрыть контур, когда выбранная сетка находится за другой сеткой. Это имеет смысл, учитывая мой процесс, так как я просто рендерил 2d контур шейдера из буфера кадра после рендеринга остальной части сцены.
Два снимка экрана моих результатов ниже. Первый - «хороший» контур, второй - где контур виден над сеткой, которая блокирует источник контура.
Процесс рендеринга выполняется следующим образом: 1) Рисуем только альфа выделенного меша, захватывая черный силуэт в буфере кадров (framebuffer1).
2) Передайте текстуру из framebuffer1 во второй шейдер, который выполняет обнаружение края. Захват края в кадровом буфере2.
3) Рендеринг всей сцены.
4) Визуализируйте текстуру из framebuffer2 поверх сцены.
У меня есть несколько идей о том, как это сделать, и я надеюсь получить отзывы об их обоснованности или о более простых или лучших методах.
Во-первых, я подумал о рендеринге всей сцены в буфер кадров и сохранении видимого силуэта подсвеченной сетки в альфа-канале (все белые сохраняются там, где выделенная сетка видна). Затем я бы выполнил определение края на альфа-канале, визуализировал буфер кадра сцены и затем отрисовал край сверху. В результате чего-то вроде этого:
Чтобы достичь этого, я подумал об установке определения только во время прохождения рендеринга выделенного объекта, который будет рисовать весь черный в альфа для любых видимых пикселей.
Моя вторая идея - использовать текущий процесс рендеринга, описанный выше, но также сохранять координаты X, Y и Z в каналах R, G и B framebuffer1 при рендеринге силуэта выбранной сетки. Обнаружение краев будет выполнено и сохранено в framebuffer2, но я передам значения RGB / XYZ от краев альфы до силуэта. Затем при рендеринге сцены я бы проверил, находится ли координата внутри края, сохраненного в framebuffer2. Если это так, я бы тогда проверил глубину текущего фрагмента, чтобы определить, находится ли он перед или позади координат, извлеченных из каналов RGB (преобразованных в пространство камеры). Если фрагмент находится перед координатами глубины, фрагмент будет отображаться нормально. Если фрагмент находится позади, он будет представлен как сплошной цвет контура.
Я использую LibGDX для этого проекта и хотел бы поддерживать WebGL и OpenGL ES, поэтому ни одно из решений, включающих геометрические шейдеры или более новые функции GLSL, не доступно для меня. Если бы кто-то мог прокомментировать мои предложенные подходы или предложить что-то лучшее, я был бы очень признателен.