Comportamento delle trame trasparenti in WebGL

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

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

UN: Albero sopra casa B: Trasparenza della finestra

Entrambi gli screenshot sono stati realizzati sullo stesso scenario contemporaneamente da diverse posizioni della telecamera. Le trame sono prodotte dallo stesso algoritmo.

Non riesco a capire qual è la differenza tra trasparenza di windows e rami. La mia domanda principale è: come sistemare i rami in modo da non hide gli oggetti dietro di loro? Il codice Shader è:

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

Ho giocato con enable / disable blending e depth_test, a volte ottenendo i risultati desiderati, ma non sono sicuro che sia il modo corretto di fare le cose.

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

Quello che sta succedendo è che l’ordine in cui si esegue il rendering della geometria trasparente sta influenzando la tua 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’object 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 grandi motori di gioco commerciali sono ancora in qualche modo in difficoltà, quindi non sentirsi male a causa di una certa confusione. 🙂

Non esiste una “soluzione perfetta” per questo problema, ma quello che in realtà si riduce consiste nel provare a strutturare la scena in questo modo:

  1. Rendi qualsiasi geometria opaca ordinata per stato (shader / texture / etc)
  2. Rendi successiva qualsiasi geometria trasparente. Se ansible, 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.

Scarta i frammenti con un’alfa inferiore a, ad esempio 0.5 potrebbe aiutare (ovviamente, c’è un effetto collaterale).

se (gl_FragColor.a <0.5) scartare;

AlphaFunctions in WebGL?