64 votes

Obtenir la vraie valeur z du tampon de profondeur

L'échantillonnage à partir d'un tampon de profondeur dans un shader renvoie des valeurs comprises entre 0 et 1, comme prévu. Étant donné les plans proches et lointains de la caméra, comment calculer la vraie valeur z à ce point, c'est-à-dire la distance à la caméra ?

15voto

david van brink Points 2331

Je sais que c'est une vieille, vieille question, mais je me suis retrouvé ici plus d'une fois à plusieurs reprises, alors j'ai pensé partager mon code qui effectue les conversions avant et arrière.

Ceci est basé sur la réponse de @ Calvin1602. Ceux-ci fonctionnent en GLSL ou en code C simple.

 uniform float zNear = 0.1;
uniform float zFar = 500.0;

// depthSample from depthTexture.r, for instance
float linearDepth(float depthSample)
{
    depthSample = 2.0 * depthSample - 1.0;
    float zLinear = 2.0 * zNear * zFar / (zFar + zNear - depthSample * (zFar - zNear));
    return zLinear;
}

// result suitable for assigning to gl_FragDepth
float depthSample(float linearDepth)
{
    float nonLinearDepth = (zFar + zNear - 2.0 * zNear * zFar / linearDepth) / (zFar - zNear);
    nonLinearDepth = (nonLinearDepth + 1.0) / 2.0;
    return nonLinearDepth;
}

0voto

Chet Points 312

Je me suis retrouvé ici à essayer de résoudre un problème similaire lorsque le commentaire de Nicol Bolas sur cette page m'a fait comprendre ce que je faisais mal. Si vous voulez la distance à la caméra et non la distance au plan de la caméra, vous pouvez la calculer comme suit (en GLSL) :

 float GetDistanceFromCamera(float depth, 
                            vec2 screen_pixel, 
                            vec2 resolution) {
  float fov = ... 
  float near = ...
  float far = ...
  float distance_to_plane = near / (far - depth * (far - near)) * far;


  vec2 center = resolution / 2.0f - 0.5;
  float focal_length = (resolution.y / 2.0f) / tan(fov / 2.0f);
  float diagonal = length(vec3(screen_pixel.x - center.x,
                               screen_pixel.y - center.y,
                               focal_length));

  return distance_to_plane * (diagonal / focal_length);
}

(source) Merci à l'utilisateur de github cassfalg : https://github.com/carla-simulator/carla/issues/2287

-1voto

Calvin1602 Points 5922
float Znear = 1.0;
float Zfar = 100.0;
float Q  = Zfar / ( Zfar - Znear );
float inv_Zfar = 1.0 / Zfar;

// Sampling
float depth = texture2D(depth_sampler,gl_TexCoord[0].xy).r;
// Linerization
float linearDepth = inv_Zfar / (Q - depth);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X