Некоторое время я пытался найти способ прочитать значение глубины для конкретной координаты мыши (x, y). Все отлично работает на win10 с opengl 4.x, но не на opengl es 3.x
Мои подходы:
- glReadPixels() не работает с openGL для буфера глубины
- ray cast не подходит, так как работаю с большой моделью местности
следующий метод был бы достаточным, но, к сожалению, слишком неточным, также на win10, но почему?
#version 420 uniform vec2 screenXy; uniform vec2 screenSize; out vec4 fragColor; void main(void) { if((int(gl_FragCoord.x) == int(screenXy.x)) && ((int(screenSize.y) - int(gl_FragCoord.y)) == int(screenXy.y))) { fragColor.r = gl_FragCoord.z; } else { fragColor = vec4(1, 1, 1, 1.0); } }
Я передаю координаты xy мыши фрагментному шейдеру (screenXy). Если щелкнутый пиксель находится в строке, я записываю значение глубины в цветовой буфер. Это работает, но значение gl_FragCoord.z и значение из буфера глубины не совсем совпадают (я знаю, что это значение из буфера глубины правильное). Хотя gl_FragCoord.z и значение буфера глубины плавающее, а так я думаю 32bit.
GLfloat zd; // from depth buffer
GLfloat zc[4]; // from color buffer
m_func->glReadPixels(xy.x(), m_pFbo->height() - xy.y(), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &zd);
m_func->glReadPixels(xy.x(), m_pFbo->height() - xy.y(), 1, 1, GL_RGBA, GL_FLOAT, zc);
Причины:
- отклонение происходит через внутреннее преобразование типов, но где?
- потому что GL_DEPTH_TEST выполняется после того, как фрагментшейдер gl_FragCoord.z не ближайший (к камере), а сохранен в буфере глубины. Таким образом, также не имеет смысла сохранять gl_FragCoord.z в отдельном Frambuffer, потому что это неправильное значение.
Может быть, кто-нибудь поможет мне и разгадать узел, потому что я не могу найти другого объяснения?
Вот некоторые измеренные значения:
zc 0.984314
zd 0.985363
zc 0.552941
zd 0.554653
zc 1 -> extremly critical
zd 0.999181