Estoy trabajando en la configuración de un esquema activo en mi motor 3D, un efecto de resaltado para personajes 3D seleccionados o paisajes en la pantalla. Después de trabajar con el búfer de la plantilla y obtener algunos resultados insatisfactorios (problemas con las formas cóncavas, el grosor del contorno debido a la distancia de la cámara y las inconsistencias entre mi computadora de escritorio y la computadora portátil), cambié a la detección de bordes y al muestreo del búfer de cuadro y obtuve un esquema. bastante satisfecho con
Sin embargo, no puedo ocultar el contorno cuando la malla seleccionada está detrás de otra malla. Esto tiene sentido dado mi proceso, ya que simplemente renderizo el contorno del sombreador 2D desde un búfer de cuadros después de renderizar el resto de la escena.
Dos capturas de pantalla de mis resultados están a continuación. El primero es un esquema "bueno", el segundo es donde se ve el esquema sobre una malla que bloquea la fuente del esquema.
El proceso de renderizado se ejecuta así: 1) Dibuje solo el alfa de la malla resaltada, capturando una silueta negra en un búfer de cuadro (framebuffer1).
2) Pase la textura de framebuffer1 a un segundo sombreador que realice la detección de bordes. Capture el borde en framebuffer2.
3) Renderiza toda la escena.
4) Renderiza la textura de framebuffer2 en la parte superior de la escena.
Tengo algunas ideas sobre cómo lograrlo y espero recibir comentarios sobre su validez, o sobre métodos más simples o mejores.
Primero, he pensado en representar toda la escena en un búfer de cuadro y almacenar la silueta visible de la malla resaltada en el canal alfa (todo blanco excepto donde la malla resaltada es visible). Luego realizaría la detección de bordes en el canal alfa, renderizaría el búfer de cuadro de escena y luego renderizaría el borde en la parte superior. Resultando en algo como esto:
Para lograr esto, pensé en establecer una definición solo durante el paso de renderizado del objeto resaltado que dibujaría todo negro en el alfa para cualquier píxel visible.
Mi segunda idea es utilizar el proceso de renderizado actual descrito anteriormente, pero también almacenar las coordenadas X, Y y Z en los canales R, G y B de framebuffer1 cuando renderice la silueta de la malla seleccionada. Las detecciones de bordes se realizarían y almacenarían en framebuffer2, pero pasaría los valores RGB / XYZ desde los bordes del alfa a la silueta. Luego, al renderizar la escena, probaría si la coordenada está dentro del borde almacenado en framebuffer2. Si es así, probaría la profundidad del fragmento actual para determinar si está delante o detrás de las coordenadas extraídas de los canales RGB (convertidos en espacio de cámara). Si el fragmento está delante de las coordenadas de profundidad, el fragmento se representará normalmente. Si el fragmento está detrás, se representará como el color del contorno sólido.
Estoy usando LibGDX para este proyecto y me gustaría admitir WebGL y OpenGL ES, por lo que ninguna de las soluciones que involucran sombreadores de geometría o funciones GLSL más nuevas están disponibles para mí. Si alguien pudiera comentar sobre mis enfoques propuestos o proponer algo mejor, realmente lo agradecería.