Je travaille sur la configuration d'un contour actif dans mon moteur 3D, un effet de surbrillance pour les personnages 3D sélectionnés ou les décors à l'écran. Après avoir travaillé avec le tampon de pochoir et obtenu des résultats insatisfaisants (problèmes avec les formes concaves, l'épaisseur du contour en raison de la distance de la caméra et les incohérences entre mon ordinateur de bureau et portable), je suis passé à la détection des bords et à l'échantillonnage du tampon de cadre et j'ai obtenu un contour que je suis assez satisfait de.
Cependant, je ne suis pas en mesure de masquer le contour lorsque le maillage sélectionné se trouve derrière un autre maillage. Cela est logique compte tenu de mon processus, car je rend simplement le contour du shader 2D à partir d'un tampon d'image après avoir rendu le reste de la scène.
Deux captures d'écran de mes résultats sont ci-dessous. Le premier est un "bon" contour, le second est l'endroit où le contour est vu sur un maillage qui bloque la source du contour.
Le processus de rendu se déroule comme suit: 1) Dessinez uniquement l'alpha du maillage en surbrillance, capturant une silhouette noire dans un tampon d'image (framebuffer1).
2) Passez la texture de framebuffer1 à un deuxième shader qui effectue la détection des contours. Capturez le bord dans framebuffer2.
3) Rendez la scène entière.
4) Rendez la texture du framebuffer2 en haut de la scène.
J'ai quelques idées sur la façon d'accomplir et j'espère obtenir des commentaires sur leur validité, ou sur des méthodes plus simples ou meilleures.
Tout d'abord, j'ai pensé à rendre la scène entière dans un tampon d'image et à stocker la silhouette visible du maillage en surbrillance dans le canal alpha (tout blanc sauf où le maillage en surbrillance est visible). J'effectuerais ensuite la détection de bord sur le canal alpha, rendrais le tampon de cadre de scène, puis rendrais le bord sur le dessus. Il en résulte quelque chose comme ceci:
Pour ce faire, j'ai pensé à définir une définition uniquement pendant la passe de rendu de l'objet en surbrillance qui dessinerait tout le noir dans l'alpha pour tous les pixels visibles.
Ma deuxième idée est d'utiliser le processus de rendu actuel décrit ci-dessus, mais également de stocker les coordonnées X, Y et Z dans les canaux R, G et B de framebuffer1 lors du rendu de la silhouette du maillage sélectionné. Les détections de bord seraient effectuées et stockées dans framebuffer2, mais je transmettrais les valeurs RVB / XYZ des bords de l'alpha à la silhouette. Ensuite, lors du rendu de la scène, je testerais si la coordonnée est dans le bord stocké dans framebuffer2. Si c'est le cas, je testerais ensuite la profondeur du fragment actuel pour déterminer s'il se trouve devant ou derrière les coordonnées extraites des canaux RVB (converties en espace caméra). Si le fragment est devant les coordonnées de profondeur, le fragment sera rendu normalement. Si le fragment est derrière, il serait rendu comme la couleur de contour solide.
J'utilise LibGDX pour ce projet et je voudrais prendre en charge WebGL et OpenGL ES, donc aucune des solutions impliquant des shaders de géométrie ou des fonctions GLSL plus récentes n'est à ma disposition. Si quelqu'un pouvait commenter mes approches proposées ou proposer quelque chose de mieux, je l'apprécierais vraiment.