GLSL gl FragCoord.Z calcul et réglage gl FragDepth

donc, j'ai un imposteur (la géométrie réelle est un cube, peut-être coupé, et la géométrie de l'imposteur est une éponge de Menger) et je dois calculer sa profondeur.

je peux calculer la quantité de décalage dans l'espace assez facilement. Malheureusement, j'ai passé des heures à défaut de perturber la profondeur.

Le seul bon résultats je peux obtenir sont quand je vais:

gl_FragDepth = gl_FragCoord.z

en gros, j'ai besoin de savoir comment gl_FragCoord.z est calculé de sorte que I pouvez:

  • prendre la transformation inverse de gl_FragCoord.z-eye espace
  • ajouter la perturbation de profondeur
  • transformez cette profondeur perturbée dans le même espace que le gl_FragCoord original.z.

Je m'excuse si cela ressemble à une question dupliquée; il y a un certain nombre d'autres Billets ici qui traitent de choses similaires. Cependant, après les avoir toutes mises en œuvre, aucune ne fonctionne correctement. Plutôt que d'essayer d'en choisir un pour obtenir de l'aide avec, à ce stade, je demande le code complet qui le fait. Ça ne devrait être que quelques lignes.

18
demandé sur genpfault 2012-04-22 07:21:51

2 réponses

référence Pour l'avenir, le code de la clé est:

float far=gl_DepthRange.far; float near=gl_DepthRange.near;

vec4 eye_space_pos = gl_ModelViewMatrix * /*something*/
vec4 clip_space_pos = gl_ProjectionMatrix * eye_space_pos;

float ndc_depth = clip_space_pos.z / clip_space_pos.w;

float depth = (((far-near) * ndc_depth) + near + far) / 2.0;
gl_FragDepth = depth;
29
répondu imallett 2012-10-15 21:11:40

pour une autre référence future, c'est la même formule que celle donnée par imallett, qui travaillait pour moi dans une application OpenGL 4.0:

vec4 v_clip_coord = modelview_projection * vec4(v_position, 1.0);
float f_ndc_depth = v_clip_coord.z / v_clip_coord.w;
gl_FragDepth = (1.0 - 0.0) * 0.5 * f_ndc_depth + (1.0 + 0.0) * 0.5;

Ici modelview_projection 4x4 modelview-matrice de projection et v_position est-objet de l'espace de la position du pixel en cours de rendu (dans mon cas, calculé par un raymarcher).

L'équation provient de l' coordonnées de la fenêtre article de manuel. Notez que dans mon code, près de 0.0 et la mesure est 1.0, qui sont les valeurs par défaut de gl_DepthRange. Notez que gl_DepthRange la même chose que la distance proche/loin dans la formule pour matrice de projection en perspective! Le seul truc, c'est à l'aide de la 0.0 et 1.0 (ou gl_DepthRange dans le cas où vous avez réellement besoin de le changer), j'ai eu du mal pendant une heure à l'autre de la profondeur de la gamme, mais qui est déjà "cuit" dans mon (point de vue) de la matrice de projection.

Notez que de cette façon, l'équation contient vraiment juste une simple multiplication par une constante ((far - near) / 2) et une seule addition d'une autre constante ((far + near) / 2). Comparez cela à multiplier, ajouter et diviser (éventuellement converti en multiplier par un compilateur d'optimisation) qui est requis dans le code d'imallett.

4
répondu the swine 2015-04-01 17:40:18