Как получить точную 3D-глубину от щелчка мыши на 2D-экране для крупномасштабного объекта в OpenGL?

Я вычисляю 3D-координаты по щелчку мыши на 2D-экране. Затем я рисую точку по вычисленной 3D-координате. В коде все в порядке, в методе все в порядке, все работает нормально. Но есть одна проблема, которая имеет отношение к глубине.

Если размер объекта около (1000, 1000, 1000), я получаю полную глубину, точную трехмерную координату поверхности объекта. Но когда я загружаю объект с размером (20000, 20000, 20000), я не получаю точные (глубину) 3D-координаты. Я получаю некоторое смещение от поверхности. Точка рисуется с некоторым смещением от поверхности. Итак, мой первый вопрос: почему это происходит? и второй вопрос: как я могу получить полную глубину и точную 3D-координату для очень крупных объектов?

Я рисую трехмерную точку с помощью

glDepthFunc(GL_LEQUAL);
glDepthRange(0.0, 0.999999);

и используя

glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &wz);
if(wz > 0.0000001f && wz < 0.999999f)
{
gluUnProject()....saving 3D coordinate
}

person maxpayne    schedule 09.06.2015    source источник


Ответы (2)


Причиной этого является ограниченная точность буфера глубины. Например, 8-битный буфер глубины может хранить только 2^8=256 различных значений глубины.

Второй набор параметров, влияющий на точность глубины, — это настройки для ближней и дальней плоскости в проекции, поскольку это диапазон, который необходимо сопоставить с доступными значениями данных в буфере глубины. Если установить этот диапазон равным [0, 100] с использованием 8-битного буфера глубины, то фактическая точность составит 100/256 = ~0,39, что означает, что приблизительно 0,39 единицы в пространстве глаза будут иметь одинаковое назначенное значение глубины.

Теперь о вашей проблеме: скорее всего, у вас слишком мало битов, назначенных буферу глубины. Как описано выше, это приводит к ошибке, поскольку невозможно сохранить точное значение глубины. Вот почему точки находятся близко к поверхности, но не точно на ней.

person BDL    schedule 09.06.2015
comment
спасибо, ваше ценное объяснение обязательно будет рассмотрено. Проблема заключалась в диапазоне глубины, который должен быть от 0,0 до 1,0. Я мог бы изменить его где-то. - person maxpayne; 10.06.2015
comment
На практике 8-битных буферов глубины не существует. Однако 16-битные буферы глубины обычно столь же неадекватны ;) Также стоит упомянуть, что точность в буфере глубины с фиксированной точкой зрения (традиционный) смещена так, что объекты, расположенные ближе к ближней плоскости, имеют больше, и точность падает по мере того, как вы приближаетесь к ней. дальний самолет. Я никогда не ожидал получить точное значение из буфера глубины, но чем дальше вы уходите, тем менее точным оно становится. - person Andon M. Coleman; 10.06.2015

Я решил эту проблему, которая происходила из-за диапазона глубины. Поскольку OpenGL — это конечный автомат, я думаю, что мог бы где-то изменить диапазон глубины, который должен быть от 0,0 до 1,0. Я думаю, что всегда лучше указывать диапазон глубины сразу после очистки буфера глубины, раньше у меня были следующие настройки сразу после очистки буфера глубины и цвета.

Решение:

{
    glClearColor(0.0,0.0,0.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glDepthRange(0.0, 1.0);
    glDepthMask(GL_TRUE);
}
person maxpayne    schedule 09.06.2015