8
votes

Profondeur comme distance du plan de la caméra dans GLSL

J'ai une paire de shaders GLSL qui me donnent la carte de profondeur des objets de ma scène. Ce que je reçois maintenant, c'est la distance de chaque pixel à la caméra. Ce dont j'ai besoin, c'est d'obtenir la distance entre le pixel dans le plan de la caméra. Laissez-moi illustrer avec un petit dessin

uniform vec3 eyePosition;
varying vec3 position;


void main(void) {
        vec3 temp = vec3(1.0,1.0,1.0);
        float depth = (length(eyePosition - position*temp) - 1.0) / 49.0;
        gl_FragColor = vec4(depth, depth, depth, 1.0);
}


3 commentaires

Quel type de projection utilisez-vous? Si vous utilisez une projection orthographique lorsque vous rendant la carte de profondeur, vous devez obtenir ce dont vous avez besoin sans calculs.


Je fais une projection en perspective lorsque vous rendant, mais j'ai besoin que les valeurs de profondeur proviennent de la projection orthographique.


Le diagramme à gauche n'est pas correct, je pense. Les distances sont dans un avion. La ligne avec des tirets devrait avoir environ la moitié des tirets.


3 Réponses :


1
votes

Qu'est-ce que vous allez faire référence à la projection orthographique. Vous utilisez actuellement la projection de la perspective. En fait, vous n'avez pas la vraie distance du pixel à la caméra, mais plutôt la position Z du pixel dans le tronc. Sur la texture rendue, la profondeur de Z finale de la plage de [-1,1] est rendue, qui décrit son composant Z dans l'espace NDC.

Comme vous le comprenez, tous vos points sont projetés (vraiment sur le proche avion) ​​la caméra à l'aide d'une projection de perspective. Ce que vous voulez, c'est de les projeter orthographiquement vers l'avion proche. Ce lien décrit les matrices de projection en détail et le résultat final des matrices sont à la bas. Vos shaders devraient pouvoir gérer la nouvelle matrice de projection tout à fait. Assurez-vous simplement que votre matrice MVP est calculée comme indiqué ci-dessus. P>

La projection orthographique note ne représente probablement pas la profondeur de votre scène rendue. Si vous rendant votre scène sur l'écran avec une projection de perspective et que vous souhaitez approfondir chaque pixel, vous devez utiliser la même projection de la perspective en conséquence. Donc, rendre votre profondeur à l'aide de la projection orthographique ne serait utile que si votre scène utilise la même projection, ou si certains algorithmes nécessitent des informations de profondeur sans rapport avec la scène, comme indiqué sur l'écran. P>

Je suggère de regarder regarder Profils Core OpenGL (3.x) Comme vous semblez utiliser une fonctionnalité obsolète (GL_VERTEX, GL_MODELVIEWPROJEXMATRIX et ALIKE). Il est légèrement plus de travail pour mettre en place tous les tampons et les shaders vous-même, mais cela pars à la fin. P>

edit strong> p>

effectivement, après votre commentaire , Je comprends ce que tu veux. Il n'était pas clair que vous vouliez les rendre dans le même appel, car je suggère quelque chose comme celui-ci dans votre fragment Shader: P>

uniform mat4 orthographicMatrix;
varying vec3 position;

void main(void) {
        vec4 clipSpace = orthographicMatrix * vec4(position, 1.0);
        gl_FragColor = vec4(clipSpace.zzz, 1.0);
}


2 commentaires

Merci pour la réponse détaillée. Je am Essayez d'obtenir la profondeur correspondant à la projection orthogonale tout en rendant la projection de la perspective. Cela peut sembler étrange mais c'est ce que je dois faire.


Oh je vois, je pense que je comprends ce que tu voulais dire. Édité mon post.



15
votes

Vous essayez vraiment de faire cela la voie difficile. Transformez simplement les choses en espace de la caméra et travaillez à partir de là.

varying float distToCamera;

void main()
{
    vec4 cs_position = glModelViewMatrix * gl_Vertex;
    distToCamera = -cs_position.z;
    gl_Position = gl_ProjectionMatrix * cs_position;
}


1 commentaires

Vous avez raison, j'étais un peu en train de le faire de la dure. En outre, j'assume -cs.z is -cs_position.z. Merci pour l'extrait de code!



2
votes

W Composant après la projection contient la profondeur orthogonale dans la scène. Vous n'avez pas besoin d'utiliser une matrice de modèle et des matrices de projection séparées pour cela:

varying float distToCamera;

void main()
{
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    distToCamera = gl_Position.w;
}


1 commentaires

Est-ce que ça? N'est-ce pas gl_position.z / gl_position.w ?