Comment puis-je réduire le crénelage dans mon effet de contour brillant?

42

J'essaie de reproduire l'effet de contour brillant dans le jeu Left 4 Dead. L'effet fait briller le contour des objets, même lorsque l'objet est occlus. Voici une capture d'écran de l'effet:

entrez la description de l'image ici

Je suis un peu capable de reproduire cet effet dans mon programme basé sur OpenGL. C'est ce que je suis en train de faire:

  • Créez une texture de couleur et de profondeur correspondant à la moitié de la taille de l'écran pour le rendu des objets lumineux
  • Effacez les textures de couleur / profondeur luminescentes. La couleur est effacée au noir.
  • Pour chaque objet brillant, convertissez-le en texture éclatante sous forme de couleur unie
  • Effectuer un flou gaussien séparable sur la texture luminescente
  • Rendre la scène en pleine résolution comme d'habitude
  • Mélangez de manière additive la texture luminescente avec la scène normale, mais utilisez la texture luminescente pour masquer l'objet en ne laissant que les contours flous.

Voici une capture d'écran de mon approche:

entrez la description de l'image ici

Voici le fragment shader qui combine la texture luminescente avec la scène:

uniform sampler2D glowColorTex;
uniform sampler2D glowDepthTex;
uniform sampler2D sceneColorTex;
void main()
{
    vec2 uv = gl_TexCoord[0].st;

    vec4 color = texture2D( sceneColorTex, uv);

    float depth = texture2D( glowDepthTex, uv).r;
    if(depth == 1.0) {
        color += 2.0 * texture2D( glowColorTex, uv);
    }

    gl_FragColor = color;
}

Comme vous pouvez le constater, cela semble fonctionner dans l’ensemble, mais le pseudonyme sur le contour est vraiment mauvais.

Quelqu'un a-t-il des suggestions pour lisser le bord intérieur du contour?

Devrais-je échantillonner les valeurs de profondeur voisines de chaque pixel et redimensionner la lueur en fonction du nombre de valeurs de profondeur égales à 1,0?

Ou existe-t-il une meilleure approche qui produira des résultats plus uniformes?

flashk
la source

Réponses:

13

Peut-être qu'au lieu de le comparer au tampon de profondeur basse résolution, vous pouvez utiliser le test du pochoir. Lors du rendu de la scène normale, il vous suffit de restituer l'objet devant briller dans le tampon de stencil (sans test de profondeur, je pense), puis de mélanger la texture de lueur complète, mais de configurer le test de stencil pour qu'il ne passe que là où se trouve le tampon de stencil. donc pas masqué, masquant donc l’objet haute résolution.

De cette façon, vous obtenez la silhouette exacte de l'objet d'origine, alors qu'un lissage des bords ne donnerait que des résultats approximatifs, mais ceux-ci vous suffiraient peut-être.

Chris dit Réintégrer Monica
la source
Merci, ça aide vraiment. J'espérais une technique qui prendrait en charge une forme d'anti-aliasing, mais c'est toujours une amélioration majeure.
flashk