2012-01-06 20 views
15

Ambiente: WebGL, Chrome. Ho il seguente comportamento quando uso png trasparenti come trame per i modelli:Comportamento delle trame trasparenti in WebGL

  1. Immagine A: l'albero nasconde l'edificio dietro di esso e vedo la trama della scatola del mondo. Si nasconde anche (sportelli posteriori non sono visibili)
  2. Allo stesso tempo - Immagine B - funziona correttamente, la finestra è trasparente e vedo cosa c'è dietro

A: Tree over house B: Window transparency

Entrambe le schermate sono state realizzate contemporaneamente sulla stessa scena da diverse posizioni della telecamera. Le trame sono prodotte dallo stesso algoritmo.

Non riesco a capire quale sia la differenza tra trasparenza di finestre e rami. La mia domanda principale è: come sistemare i rami in modo da non nascondere gli oggetti dietro di loro? Codice Shader è:

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

Ho giocato con abilitare/disabilitare la miscelazione e depth_test, a volte ottenendo i risultati desiderati, ma non è sicuro se è il modo corretto di fare le cose.

risposta

28

Stai riscontrando problemi con il buffer di profondità, non ha nulla a che fare con lo shader o le modalità di fusione.

Che cosa sta succedendo è che l'ordine in cui si esegue il rendering della geometria trasparente influisce sulla capacità di eseguire il rendering dietro di esso. Questo perché il buffer di profondità non ha alcun concetto di trasparente o non trasparente. Di conseguenza, anche se non contribuiscono visivamente alla scena, quei pixel trasparenti si scrivono nel buffer di profondità in ogni caso, e dopo di ciò i pixel che si disegnano dietro di essi saranno scartati perché "non visibili". Se si disegnava prima la geometria dietro l'oggetto trasparente, tuttavia, essa si mostra correttamente perché viene scritta nel frame prima che la profondità trasparente venga messa in posizione per scartarla.

Questo è qualcosa che anche i motori di gioco commerciali di grandi dimensioni sono ancora in difficoltà, quindi non sentirsi in colpa per questo causando una certa confusione. :)

Non c'è "soluzione perfetta" per questo problema, ma ciò che realmente si riduce a sta cercando di strutturare la vostra scena in questo modo:

  1. Render qualsiasi geometria opaco ordinati per stato (Shader/texture/ecc.)
  2. Rendi successiva qualsiasi geometria trasparente. Se possibile, ordinali in base alla profondità, in modo da disegnare per prima la più lontana dalla fotocamera.

Semplicemente contrassegnando i bit di geometria che sono trasparenti e rendendoli dopo tutto il resto risolverai il 90% di questo problema, ma il problema potrebbe rimanere per oggetti trasparenti sovrapposti. Questo potrebbe non essere un problema per te, a seconda della scena, ma se causa ancora artefatti dovrai ordinare gli oggetti trasparenti per profondità prima di disegnare.

+0

Grazie per la risposta chiara. Posso eseguire il rendering nell'ordine richiesto. Solo il problema rimanente quindi - si sovrappongono automaticamente. L'albero nell'esempio "nasconde" i rami posteriori di fronte. Supponiamo che sia impossibile risolverlo con i metodi usuali. Almeno il 90% dei problemi ora viene risolto, eseguendo il rendering nell'ordine corretto. – Vecnas

+0

@Toji C'è un buon approccio per ordinare gli oggetti in base alla profondità? Greeings – schlenger

3

Scarta frammenti con alfa inferiore a, ad esempio 0,5 potrebbe aiutare (ovviamente, c'è un effetto collaterale).

if (gl_FragColor.a < 0.5) scarto;

AlphaFunctions in WebGL?

+0

Si prega di aggiungere anche il codice. –