2010-12-26 2 views

Répondre

7

Le tampon de profondeur est plus obscurci que vous ne le pensez dans OpenGL ES; non seulement glDrawPixels est absent, mais gl_FragDepth a été supprimé de GLSL. Vous ne pouvez donc pas écrire un shader de fragment personnalisé pour spouler des valeurs dans le buffer de profondeur car vous pourriez pousser des couleurs.

La solution la plus évidente consiste à conditionner vos informations de profondeur dans une texture et à utiliser un fragment de fragment personnalisé qui effectue une comparaison de profondeur entre le fragment généré et celui recherché à partir d'une texture que vous fournissez. Ce n'est que si le fragment généré est plus proche qu'il est autorisé à continuer. Le tampon de profondeur normale attrapera d'autres cas d'occlusion et - en principe - vous pourriez utiliser un objet framebuffer pour créer la texture de profondeur en premier lieu, vous offrant un aller-retour complet sur GPU, même s'il n'est pas directement pertinent problème.

Les inconvénients sont que le dessin vous coûtera une unité de texture supplémentaire et les textures utiliseront des composants entiers.

EDIT: dans le but de garder l'exemple simple, supposons que vous empaquiez toutes vos informations de profondeur dans le canal rouge d'une texture. Ce serait vous donner une très faible profondeur de mémoire tampon de précision, mais juste pour garder les choses claires, vous pouvez écrire un fragment shader rapide comme:

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

à la profondeur de magasin dans le canal rouge. Vous avez donc partiellement recréé l'ancienne extension de texture en profondeur: vous obtenez une image dont le rouge est plus clair dans les pixels plus proches, et un rouge plus foncé dans les pixels les plus éloignés. Je pense que dans votre question, vous chargiez cette image à partir du disque.

Pour utiliser ensuite la texture dans un futur fragment shader, vous feriez quelque chose comme:

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: vous pouvez voir une cartographie beaucoup plus intelligente de la profondeur à une valeur RGBA here. Pour se connecter directement à ce document, OES_depth_texture n'est définitivement pas supporté sur l'iPad ou sur l'iPhone de troisième génération. Je n'ai pas fait de test complet ailleurs.

+0

Merci pour votre réponse. Pourriez-vous nous en dire un peu plus sur le voyage aller-sur-GPU dont vous parlez? Je ne suis pas certain de comprendre cette partie. – sharvey

+0

Ce n'est pas tout à fait pertinent pour la question que vous posiez - c'est plus pertinent pour le type de question «comment utiliser une carte de profondeur pour l'ombrage», où vous dessinez réellement quelque chose pour créer une carte de profondeur sur le GPU pour plus tard plutôt que de le charger à partir du disque. Mais j'ai ajouté un peu d'exemple de code, qui peut être encore un peu vague? – Tommy

+0

Wow, merci beaucoup. – sharvey

Questions connexes