2012-01-06 13 views
15

Entorno: WebGL, Chrome. Tengo el siguiente comportamiento cuando se utiliza transparentes del png como texturas para los modelos:Comportamiento de texturas transparentes en WebGL

  1. imagen A - el árbol esconde el edificio detrás de él y veo la caja mundo textura. También se oculta (ramas traseras no son visibles)
  2. Al mismo tiempo - Imagen B - funciona correctamente, la ventana es transparente y ver lo que hay detrás

A: Tree over house B: Window transparency

Ambas capturas de pantalla se realizaron en la misma escena al mismo tiempo desde diferentes posiciones de la cámara. Las texturas son producidas por el mismo algoritmo.

No puedo entender cuál es la diferencia entre la ventana y la transparencia de las ramas. Mi pregunta principal es: ¿cómo arreglar las ramas para no ocultar los objetos detrás de ellas? código de shader es:

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

jugaba con activar/desactivar la mezcla y depth_test, a veces conseguir los resultados deseados, pero no está seguro si es la forma correcta de hacer las cosas.

Respuesta

28

Te encuentras con problemas de buffer de profundidad, no tiene nada que ver con tus modos shader o blend.

Lo que está sucediendo es que el orden en que representa su geometría transparente está afectando su capacidad para representar detrás de él. Esto se debe a que el búfer de profundidad no tiene ningún concepto de transparente o no transparente. Como resultado, aunque no contribuyan visualmente a la escena, esos píxeles transparentes se escriben a sí mismos en el búfer de profundidad de todos modos, y después de eso cualquier píxel que dibuje detrás de ellos se descartará porque "no está visible". Sin embargo, si primero se dibujó la geometría detrás del objeto transparente, se mostraría correctamente porque se escribe en el marco antes de que la profundidad transparente se coloque en su lugar para descartarlo.

Esto es algo que incluso los motores de juegos comerciales grandes todavía luchan con algún grado, así que no te sientas mal porque causa cierta confusión. :)

No hay "solución perfecta" para este problema, pero lo que realmente se reduce a está tratando de estructurar su escena de este modo:

  1. Render cualquier geometría opaca ordenados por estado (shader/textura/etc.)
  2. Representa a continuación cualquier geometría transparente. Si es posible, clasifícalos por profundidad, para que primero dibujes el más alejado de la cámara.

Simplemente marcando los bits de la geometría que son transparentes y representándolos después de todo lo demás, resolverá el 90% de este problema, pero el problema puede seguir siendo la superposición de objetos transparentes. Puede que no sea un problema para usted, dependiendo de su escena, pero si todavía está causando artefactos, tendrá que clasificar los objetos transparentes por profundidad antes de dibujar.

+0

Gracias por su respuesta clara. Puedo renderizar en el orden requerido. El único problema restante entonces es la auto-superposición. El árbol en el ejemplo "esconde" ramas traseras por el frente. Supongamos que es imposible resolverlo con los métodos habituales. Al menos el 90% de los problemas ahora se resuelven, renderizando en el orden correcto. – Vecnas

+0

@Toji ¿Existe un buen enfoque para ordenar los objetos por profundidad? Greeings – schlenger

3

Descartar fragmentos con alfa menor que, por ejemplo, 0.5 podría ayudar (por supuesto, hay efectos secundarios).

if (gl_FragColor.a < 0.5) descarte;

AlphaFunctions in WebGL?

+0

Por favor, agrega el código también. –