Comportement des textures transparentes dans WebGL

Environnement: WebGL, Chrome. J'ai le comportement suivant lorsque j'utilise des png transparents comme textures pour les modèles:

  1. Image a-l'arbre cache le bâtiment derrière lui et je vois la texture de la boîte du monde. Il se cache aussi (les branches arrière ne sont pas visibles)
  2. en même temps-Image B-fonctionne correctement, la fenêtre est transparente et je vois ce qui est derrière

: Tree over house B: Window transparency

les deux screenshots ont été réalisés sur la même scène en même temps à partir de différentes positions de caméra. Les Textures sont produites par le même algorithme.

Je ne peux pas comprendre quelle est la différence entre la transparence des fenêtres et des branches. Ma question principale est-comment réparer les branches pour ne pas cacher les objets derrière eux? Le code Shader est:

gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a);

j'ai joué avec enable/disable blending et depth_test, obtenant parfois les résultats désirés, mais pas sûr si c'est la bonne façon de faire les choses.

15
demandé sur Blubberguy22 2012-01-06 23:50:49

2 réponses

vous rencontrez des problèmes de tampon de profondeur, cela n'a rien à voir avec vos modes shader ou blend.

ce qui se passe, c'est que l'ordre dans lequel vous rendez votre géométrie transparente affecte votre capacité à rendre derrière elle. C'est parce que le tampon de profondeur n'a pas de notion de transparents ou opaques. Par conséquent, même s'ils ne contribuent pas visuellement à la scène, ces pixels transparents s'écrivent de toute façon dans le tampon de profondeur, et après que tous les pixels que vous dessinez derrière eux seront rejetés parce qu'ils ne sont "pas visibles". Si vous dessinez d'abord la géométrie derrière l'objet transparent, elle apparaîtrait correctement parce qu'elle est écrite dans le cadre avant que la profondeur transparente ne soit mise en place pour l'écarter.

c'est quelque chose que même les gros moteurs de jeux commerciaux ont encore du mal à supporter dans une certaine mesure, alors ne vous en plaignez pas, ce qui crée une certaine confusion. :)

il n'y a pas "solution parfaite" à ce problème, mais ce qui se résume vraiment à essayer de structurer votre scène comme cela:

  1. Rendre toute opaque géométrie triés par l'état (de shaders/texture/etc)
  2. Rendre transparente la géométrie suivant. Si possible, classez-les par profondeur, de sorte que vous dessinez le plus éloigné de la caméra en premier.

simplement en indiquant les bits de géométrie qui sont transparents et en les rendant après tout le reste vous résoudrez 90% de ce problème, mais le problème peut toujours rester pour les objets transparents qui se chevauchent. Cela peut ne pas être un problème pour vous, selon votre scène, mais si elle est toujours à l'origine des artéfacts, vous aurez besoin de trier les objets transparents par profondeur avant de dessiner.

28
répondu Toji 2012-01-07 16:33:31

jeter les fragments avec alpha inférieur à, par exemple 0,5 pourrait aider (bien sûr, il ya des effets secondaires).

si(gl_FragColor.un < 0.5) jeter;

AlphaFunctions in WebGL?

3
répondu Punyapat 2017-05-23 12:02:02