Cómo ocultar un contorno de malla postprocesado cuando / dónde está oculta la malla

10

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.

ingrese la descripción de la imagen aquí

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:

resultado

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.

nils
fuente
Eché un vistazo a tu repositorio. ¿Alguna vez encontró una solución aceptable?
iKlsR

Respuestas:

0

Procesaría toda la escena en un búfer de plantilla con el objeto delineado deseado para establecer un bit y para cualquier otra cosa descartar / eliminar el bit.

Luego, elimine la detección de bordes, no lo necesita, en su lugar puede escalar un poco el búfer. Entonces cada objeto solo crece ligeramente.

A partir de ahí, el búfer de la plantilla puede tener el contorno que necesita. Se trata de asegurarse de que los otros objetos que está renderizando estén apagando los bits en su búfer de plantilla.

NeomerArcana
fuente
2
Gracias por la respuesta. ¿Este método no tendría problemas similares con el grosor del contorno y las formas cóncavas si la escala se realiza en 3d? ¿O problemas de desplazamiento si se hiciera en 2d y el objeto delineado no estuviera en el punto muerto de la pantalla?
nils
0

1) en un objeto frame buffer, puede ejecutar un sombreador laplaciano en la GPU para obtener el contorno.

2) tiene que usar el búfer de profundidad final cuando dibuje su objeto en el FBO, de esa manera dibujará solo la parte visible de su objeto en el FBO, y el laplaciano contorneará solo la parte visible.

tinyfiledialogs
fuente
Hola, gracias por la respuesta. Ya estoy haciendo esto para lograr el esquema que tengo. Sin embargo, no creo que merezca un voto negativo por esta respuesta, por lo que debe votar.
nils
0

Espero poder aclarar esto, pero básicamente necesita hacer una plantilla de ambos objetos como si ambos estuvieran seleccionados, luego solo mantenga las áreas en el cuadro delimitador del elemento que realmente desea resaltar.

Entonces, básicamente, haces un búfer de plantilla de ambos objetos seleccionados (o de todos los objetos que ocluyen el objeto, en realidad ... pero no me preocuparía por esos casos a menos que realmente surja mucho, si es que las personas ocluidas no van a esperar esta mucha ayuda), y luego con una plantilla del cuadro delimitador para su objeto.

Eso debería tener el efecto que estás buscando.

Alternativamente, puede dejar el resultado 'malo' y no creo que a la mayoría de la gente le importe demasiado, aunque esto depende de sus datos / juego y especialmente del tamaño de los objetos.

Yudrist
fuente