PyOpenGL - получить карту глубины нарисованного изображения

1

Я нарисовал конкретную сцену, используя определенную точку зрения (используя матрицы представлений и проекций). Я использовал VBO треугольников и так один. Я могу получить RGB изображения, используя:

data = glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE)
data = np.frombuffer(data, dtype=np.uint8).reshape(width, height, 3)[::-1]
cv2.imwrite(r"c:\temp\image1.png", data)

Но получение карты глубины вызывает какой-то странный результат, состоящий в основном из 255:

data2 = glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE)
data2 = np.frombuffer(data2, dtype=np.uint8).reshape(width, height)[::-1]
cv2.imwrite(r"c:\temp\image2.png", data2)

Я попытался заменить GL_UNSIGNED_BYTEGL_FLOAT и uint8float32

Но это не помогло

  • 1
    «Но получение карты глубины дает какой-то странный результат, который состоит в основном из 255» - что такого странного? Карта глубины инициализируется 1,0, что приводит к 255, если она считывается в буфер GL_UNSIGNED_BYTE . Обратите внимание, что карта глубины находится в диапазоне [0.0, 1.0], если она читается в GL_UNSIGNED_BYTE , то этот диапазон отображается на [0, 255]
  • 0
    Странность в том, что она полностью не отражает то, что нарисовано на сцене. Сцена "полная" (треугольники нарисованы по всему изображению, без "пустых" пробелов). Кроме того - значения, которые не являются 255, очень близки к этому
Показать ещё 6 комментариев
Теги:
python-3.x
opengl
pyopengl

1 ответ

1
Лучший ответ

Карта глубины инициализируется 1.0, что приводит к 255, если она считывается в буфер GL_UNSIGNED_BYTE. Обратите внимание, что карта глубины находится в диапазоне [0.0, 1.0], если она читается GL_UNSIGNED_BYTE, тогда этот диапазон отображается на [0, 255].

При перспективной проекции z-координата не линейно отображается в буфер глубины. Значение глубины быстро увеличивается, а геометрия, близкая к дальней плоскости, приведет к значению глубины значения 255.

Если у вас есть значение глубины в диапазоне [0.0, 1.0], и вы хотите вычислить координату z пространства зрения (глаза), тогда вам нужно преобразовать значение глубины в нормализованное устройство z координатный кулак (z_ndc):

z_ndc = 2.0 * depth - 1.0;

Эта координата может быть преобразована в координату z пространства глаз (z_eye) по следующей формуле:

z_eye = 2.0 * n * f / (f + n - z_ndc * (f - n));

где n - ближайшая плоскость, f - дальняя плоскость.

Обратите внимание, что это преобразование работает только для перспективной проекции.

При ортографической проекции координата z линейно отображается на глубину. Таким образом, обратное преобразование намного проще:

z_eye = depth * (f-n) + n; 

См. Также Как визуализировать глубину линейно в современном OpenGL с gl_FragCoord.z в шейдере фрагмента?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню