В моем приложении Webgl2 у меня есть два FBO:
- Стандартное FBO, которое я использую исключительно для рисования на экране
- "запрос" FBO, которое я использую исключительно для нарисовать более простую версию сцены и затем вызвать
readPixels()
. Объекты отображаются с помощью специального фрагментного шейдера, который выводит цвет RGBA, который однозначно идентифицирует идентификатор объекта (id = A) и мировую позицию фрагмента (XYZ = RGB). Вот как я выполняю sh выбор мышью объектов на сцене.
Так я создаю FBO «запрос» (код в golang, который скомпилирован в wasm):
renderer.gl.getExtension("EXT_color_buffer_float")
renderer.queryFramebuffer = renderer.gl.CreateFramebuffer()
renderer.gl.BindFramebuffer(gl.FRAMEBUFFER, renderer.queryFramebuffer)
renderer.queryRenderbuffer = renderer.gl.CreateRenderbuffer()
renderer.gl.BindRenderbuffer(gl.RENDERBUFFER, renderer.queryRenderbuffer)
renderer.gl.RenderbufferStorage(gl.RENDERBUFFER, gl.RGBA32F, 1, 1)
renderer.gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderer.queryRenderbuffer)
queryDepthRenderbuffer := renderer.gl.CreateRenderbuffer()
renderer.gl.BindRenderbuffer(gl.RENDERBUFFER, queryDepthRenderbuffer)
renderer.gl.RenderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1, 1);
renderer.gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, queryDepthRenderbuffer)
Это сводка моих обновлений приложения c:
- Рисование всей сцены
- Привязка "запроса" FBO
renderer.gl.BindFramebuffer(gl.FRAMEBUFFER, renderer.queryFramebuffer)
Нарисуйте упрощенную версию сцены Звоните
readPixels()
renderer.gl.ReadPixels(0, 0, 1, 1, gl.RGBA, gl.FLOAT, pixelArray);
Анализировать считанные пиксели, чтобы определить, какой объект был выбран указателем (заблокирован в центре экрана) Привязать FBO
renderer.gl.BindFramebuffer(gl.FRAMEBUFFER, js.Null())
по умолчанию Нарисуйте визуальную подсказку, окружающую выбранный объект Запрос кадра анимации повторить весь процесс
window.requestAnimationFrame(update);
В итоге происходит шаг 4 занимает 16 -32 мс для выполнения , а все остальное занимает 1 мс. Я понимаю, что это потому, что вызов readPixels()
останавливает конвейер, блокируя до завершения рисования 1 или 2 кадров.
Мой вопрос: возможно ли избежать этого останова конвейера и поддерживать синхронную логику приложения * 1058? *? Мне кажется, что GPU не должен ждать очень долго, учитывая, что считываемый буфер не буфер кадра по умолчанию, и связанный с ним "упрощенный" вызов отрисовки не должен занимать много времени для выполнения.
Смежный вопрос: возможно ли остановить выполнение очереди действий графического процессора на стандартном FBO от необходимости завершения до операции readPixels()
на нестандартном FBO?
Другой связанный вопрос: даже если GPU должен выполнить действия sh на FBO по умолчанию перед операцией readPixels()
на FBO не по умолчанию, как я могу избежать чрезвычайной задержки 16-32 мс, когда рассматриваемые вызовы отрисовки FBO по умолчанию, кажется, занимают намного меньше времени самостоятельно? (16 мс не произвольно, длина одного анимационного кадра)