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 ?
Réponses
Trop de publicités?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;
}
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