2017-08-27 6 views
2

J'essaie de mélanger le raymarching et le rendu géométrique habituel mais je ne comprends pas comment comparer correctement la distance du rayon avec la valeur de profondeur I stockée sur mon tampon.OpenGL compare la distance du rayon avec le tampon de profondeur

This drawing will make it clear

Du côté raymarching, j'ai rayons à partir de l'œil (point rouge). Si vous ne restituez que des fragments à une distance de rayon fixe 'T', vous verrez une ligne courbe (en jaune sur mon dessin). Je comprends cela parce que si vous commencez à partir des origines de rayons Oa et Ob, et suivez la direction Da et Db pendant les unités T (Oa + T * Da, et Ob + T * Db), vous voyez que seul le rayon au milieu de l'écran atteint le plan bleu.

Maintenant, du côté de la géométrie, j'ai stocké des valeurs directement à partir de gl_FragCoord.z. Mais je ne comprends pas pourquoi nous ne voyons pas cet effet incurvé là. J'ai édité cette image dans gimp, en jouant avec la fonction 'posterize' pour le rendre clair.

make it clear

Nous voyons des lignes droites, pas de lignes courbes.

Je suis d'accord avec la conversion de cette valeur de profondeur à une distance (en tenant compte de la linéarisation). Mais quand je compare les deux distances, j'ai des problèmes sur le côté de mon écran.

Il me manque une chose avec la projection et la façon dont la valeur de profondeur est stockée ... Je supposais que la valeur de profondeur était la distance (remappée) du plan proche suivant la direction des rayons partant de l'œil.

EDIT: Il semble que l'écriture de cette question m'a un peu aidé. Je vois maintenant pourquoi on ne voit pas cet effet de courbe sur le buffer de profondeur: parce que la distance entre Near et Far est plus grande pour le rayon du côté de mon écran. Ainsi, même si les valeurs de profondeur sont les mêmes (écran central ou latéral), les distances ne le sont pas.

Ainsi, il semble que mon problème vient de la façon dont je convertis la profondeur en distance. J'ai utilisé le suivant:

float z_n = 2.0 * mydepthvalue - 1.0; 
float z_e = 2.0 * zNear * zFar/(zFar + zNear - z_n * (zFar - zNear)); 

Cependant, après la conversion, je ne vois toujours pas cet effet de courbe que j'ai besoin pour comparer avec ma distance de rayon. Notez que ce code ne prend pas en compte les FragCoord.x et .y, et c'est bizarre pour moi ...

+0

En OpenGL, la surface de la profondeur d'invariance est un * plan * perpendiculaire à la direction de la caméra, pas une coque sphérique (projection dite rectiligne). Par conséquent, la distance d'un rayon de la caméra à un point sur le plan varie * hyperboliquement * avec sa distance de décalage de l'axe de la caméra. – meowgoesthedog

Répondre

2

Vous complimentez le sujet. Il n'y a pas d '"effet de courbe" car un avion n'est pas courbé. Le terme z valeur litteraly décrit ce que c'est: le zcoordonner dans certains espace de coordonnées euclidien. Et dans un tel espace z=C formera un parallèle au plan enjambé par les xy -Axes de cet espace, à la distance C.

Donc si vous voulez la distance à un certain point, vous devez également prendre les coordonnées x et y. Dans l'espace des yeux, la caméra est généralement à l'origine, donc la distance à la caméra se réduit à length(x_e, y_e, z_e) (ce qui est bien sûr une opération non linéaire qui créerait la "courbe" que vous semblez attendre).

+1

Merci beaucoup! Tu as raison; Je me suis perdu. Au début, j'ai suivi [ce tutoriel] (https://www.gamasutra.com/blogs/DavidArppe/20170405/295240/How_to_get_Stunning_Graphics_with_Raymarching_in_Games.php). Mais je pense qu'il y a une erreur à ce sujet. Dans sa fonction GetDistanceFromDepth(), c'est exactement comme s'il ne considère que z_e, sans tenir compte de uv (ou de 'rd' comme indiqué dans le texte lui-même). Pour les personnes intéressées par ce sujet; il y a une bonne source: https://www.khronos.org/opengl/wiki/Compute_eye_space_from_window_space – Plaoy3D