2010-12-26 13 views

Respuesta

7

El búfer de profundidad está más oscurecido de lo que cree en OpenGL ES; no solo glDrawPixels está ausente, sino que gl_FragDepth se ha eliminado de GLSL. Por lo tanto, no puede escribir un sombreador de fragmentos personalizado para transferir valores al búfer de profundidad, ya que puede presionar colores.

La solución más obvia es empacar su información de profundidad en una textura y usar un sombreador de fragmentos personalizado que hace una comparación en profundidad entre el fragmento que genera y uno que mira desde una textura que proporciona. Solo si el fragmento generado está más cerca, puede continuar. El búfer de profundidad normal detectará otros casos de oclusión y, en principio, podría usar un objeto framebuffer para crear la textura de profundidad en primer lugar, ofreciéndole un viaje completo en la GPU, aunque no es directamente relevante para su problema.

Las desventajas son que el dibujo le costará una unidad de textura extra y las texturas usan componentes enteros.

EDITAR: con el fin de mantener el ejemplo simple, suponga que estaba empaquetando toda su información de profundidad en el canal rojo de una textura. Que le daría un buffer muy baja profundidad precisión, pero sólo para mantener las cosas claras, se podría escribir un fragment shader rápida como:

void main() 
{ 
    // write a value to the depth map 
    gl_FragColor = vec4(gl_FragCoord.w, 0.0, 0.0, 1.0); 
} 

Para tienda de profundidad en el canal rojo. Por lo tanto, ha recreado parcialmente la antigua extensión de textura de profundidad: tendrá una imagen con un rojo más brillante en píxeles que están más cerca, un rojo más oscuro en píxeles que están más alejados. Creo que en tu pregunta, realmente cargarías esta imagen desde el disco.

Para utilizar entonces la textura en un futuro fragment shader, que haría algo como:

uniform sampler2D depthMap; 

void main() 
{ 
    // read a value from the depth map 
    lowp vec3 colourFromDepthMap = texture2D(depthMap, gl_FragCoord.xy); 

    // discard the current fragment if it is less close than the stored value 
    if(colourFromDepthMap.r > gl_FragCoord.w) discard; 

    ... set gl_FragColor appropriately otherwise ... 
} 

Edit2: se puede ver un mapeo mucho más inteligente de profundidad a un valor RGBA here. Para enlazar directamente a ese documento, OES_depth_texture definitivamente no es compatible con el iPad o con el iPhone de tercera generación. No he realizado una prueba completa en otro lugar.

+0

Gracias por su respuesta. ¿Podría explicar un poco sobre el viaje de ida y vuelta de la GPU de la que está hablando? No estoy seguro de entender esa parte. – sharvey

+0

No es completamente relevante para la pregunta que estaba haciendo; es más relevante para el tipo de pregunta "¿Cómo uso un mapa de profundidad para sombrear?", Donde realmente dibuja algo para crear un mapa de profundidad en la GPU y mantener el mapa para más tarde en lugar de cargarlo desde el disco. ¿Pero he agregado un poco de código de ejemplo, que aún puede ser un poco vago? – Tommy

+0

Wow, muchas gracias. – sharvey

Cuestiones relacionadas