OpenGL es 2.0 Буфер глубины чтения - PullRequest
5 голосов
/ 08 апреля 2010

Насколько я знаю, мы не можем прочитать значение Z (глубины) в OpenGL ES 2.0. Поэтому мне интересно, как мы можем получить координаты трехмерного мира из точки на двумерном экране?

На самом деле у меня могут быть какие-то случайные мысли. Поскольку мы можем прочитать значение RGBA с помощью glReadPixels, как насчет дублирования буфера глубины и сохранения его в буфере цвета (скажем, ColorforDepth). Конечно, должно быть какое-то хорошее соглашение, чтобы мы не теряли информацию о буфере глубины. И затем, когда нам нужны мировые координаты точки, мы присоединяем этот буфер цвета ColorforDepth к кадровому буферу и затем визуализируем его. Поэтому, когда мы используем glReadPixels, чтобы прочитать информацию о глубине в этом кадре.

Однако это приведет к 1-кадровой флэш-памяти, так как цветовой буфер - странный буфер, переведенный из буфера глубины. Мне все еще интересно, есть ли какой-нибудь стандартный способ получить глубину в OpenGL es 2.0?

Спасибо заранее!:)

Ответы [ 3 ]

7 голосов
/ 26 мая 2011

Используя FBO, вы можете визуализировать без отображения результатов. Если вы используете ES 2.0, ваш шейдер фрагментов может получить доступ к глубине текущего фрагмента (в координатах окна) как часть gl_FragCoord, так что вы можете записать это в буфер цвета, используя glReadPixels, чтобы вернуть результат и продолжить. Кроме того, вы можете загрузить world-space z как переменную и записать ее из своего фрагментного шейдера, на случай, если это будет проще.

Чтобы убедить себя, попробуйте написать быстрый шейдер, который быстро выдает gl_FragCoord.z ​​с низкой точностью, например просто

gl_FragColor = vec4(vec3(gl_FragCoord.z), 1.0);

Вы должны получить оттенки серого с интенсивностью цвета, представляющего глубину. Поскольку вы находитесь в координатах окна, интенсивность будет варьироваться от 0.0 (ближайший возможный незарезанный фрагмент) до 1.0 (самый дальний возможный незажатый фрагмент). Чтобы не потерять большую точность, вероятно, более полезно разделить значение между компонентами, поскольку ваш поставщик почти наверняка не поддерживает целевые буферы с плавающей запятой.

0 голосов
/ 01 ноября 2010

Я также хотел бы иметь возможность читать значения в буфере глубины, но исследования показывают, что это невозможно сделать.

Как предполагает Винсент, если у вас есть простые формы, такие как сферы, лучевое литье, вероятно, лучше.

для более сложных форм, я думаю о рендеринге объекта в (потенциально меньший) внеэкранный буфер, вручную присваивая одну из цветовых составляющих каждой вершины глубине этой вершины, и затем чтение значений цвета. это несколько не элегантно и раздражает, и требует, чтобы вы были в состоянии преобразовать пространство объекта в пространство экрана (я использую мои собственные кватернионы для управления матрицами, так что об этом позаботится) с шейдерами может быть способ записать информацию о глубине в буфер цвета или трафарета (есть ли в GL ES даже трафаретный буфер?)

если у кого-то есть более чистый подход, я бы с удовольствием его услышал.

0 голосов
/ 13 апреля 2010

Я использую базовое наведение лучей для выбора 3D-объекта от прикосновения к экрану.На самом деле я вычисляю пересечение между нормалью экрана в точке касания и сферой, содержащей мой объект.Для очень точного выбора или сложной формы вы должны использовать несколько сфер.

Вы также можете проецировать некоторые ключевые точки вашего объекта в 2D-пространстве экрана (мое умножение вашей 3D-точки на вашу матрицу преобразования), а затемсделать некоторое 2D-сравнение (расстояние) с вашей точкой касания.

...