Я работаю над настройкой активного контура в своем 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, не доступно для меня. Если бы кто-то мог прокомментировать мои предложенные подходы или предложить что-то лучшее, я был бы очень признателен.
Ответы:
Я бы сделал всю сцену в буфере трафарета с желаемым контурным объектом, чтобы установить бит и для чего-либо еще, чтобы удалить / удалить бит.
Тогда избавьтесь от обнаружения краев, вам это не нужно, вместо этого вы можете просто немного увеличить масштаб буфера. Так что каждый объект просто немного растет.
Оттуда у вас в трафаретном буфере может быть необходимая схема. Все дело в том, чтобы другие объекты, которые вы отображаете, отключали биты в буфере трафарета.
источник
1) в объекте кадрового буфера вы можете запустить лапласианский шейдер в графическом процессоре для получения контура.
2) вы должны использовать конечный буфер глубины, когда вы рисуете свой объект в FBO, таким образом вы будете рисовать только видимую часть вашего объекта в FBO, а лапласиан будет очерчивать только видимую часть.
источник
Я надеюсь, что смогу прояснить это, но в основном вам нужно создать трафарет обоих объектов, как если бы они оба были выделены, а затем оставить только области в ограничивающей рамке элемента, который вы действительно хотите выделить.
Таким образом, в основном вы создаете один буфер трафарета для обоих выбранных объектов (или для всех объектов, которые закрывают объект, на самом деле ... но я бы не стал беспокоиться об этих случаях, если он на самом деле не возникает много - если это из-за того, что закрытые люди не будут ожидать это очень поможет), тогда и оно с трафаретом ограничительной рамки для вашего объекта.
Это должно получить эффект, который вы ищете.
В качестве альтернативы вы можете просто оставить «плохой» результат, и я не думаю, что большинство людей будут слишком сильно заботиться, хотя это зависит от ваших данных / игры и особенно от размера объектов.
источник