Как заставить WebGL немедленно выполнить рендеринг в FrameBuffer? - PullRequest
0 голосов
/ 16 января 2019

Фон - я работаю над проектом, который немного похож на After Effects или Photoshop - вы можете манипулировать различными визуальными слоями, которые в конечном итоге объединяются вместе. Меня не устраивают режимы наложения, доступные непосредственно в WebGL, поэтому я внедряю новые режимы наложения, используя шейдеры и схему многопроходного рендеринга. По сути, я рендерил каждый слой в кадровый буфер, а затем сразу же использовал кадровый буфер в качестве исходной текстуры при рендеринге следующего слоя.

Моя проблема - поскольку фрагментные шейдеры работают параллельно, слои не отображаются последовательно. Браузер пытается отобразить все слои параллельно, а затем объединить их вместе, что означает, что исходная текстура для родительского слоя данного слоя пуста при выполнении шейдера. В результате нет возможности объединять данные из предыдущего уровня. Я могу сказать, что связывание и рендеринг работают в широком смысле, учитывая, что я могу сохранить составную текстуру после рендеринга всего и использовать ее в следующем кадре, но это не то, что я ищу.

Мой вопрос - как я могу заставить WebGL растеризовать данный кадровый буфер, чтобы я мог сразу использовать его в качестве текстуры?

Ответы [ 2 ]

0 голосов
/ 16 января 2019

WebGL работает не так.

С точки зрения JavaScript и WebGL ничего не работает параллельно. Любая ошибка, которую вы видите, скорее всего, является результатом ошибки в вашем коде, а не имеет ничего общего с параллельной работой WebGL.

Из спецификации:

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

Нет случая рендеринга в кадровый буфер и его неготовности для использования результатов в вызове отрисовки.

В комментариях вы утверждаете, что вызов gl.finish исправил вашу ошибку, но это было скорее совпадением с тем, чем на самом деле является ваша ошибка.

Опубликуйте репо, если вы считаете, что видели иначе, поскольку это будет ошибка в вашем браузере и о ней следует сообщить. Вы упоминаете, что текстуры пустые. Это больше похоже на то, что вы пытаетесь визуализировать содержимое холста, и они очищаются, что является частью спецификации. Не видя ваш код, мы не можем сказать вам, какова реальная проблема, но вряд ли вы написали свой вопрос.

0 голосов
/ 16 января 2019

Я думаю, что вам доступны только два API-интерфейса: флеш и финиш. Из того, что я помню, они не работают точно так, как ожидалось в браузере. Но вы можете попробовать.

WebGLRenderingContext.flush

Метод WebGLRenderingContext.flush () опустошает API WebGL различные команды буфера, в результате чего все команды будут выполнены как как можно быстрее.

WebGLRenderingContext.finish

Метод WebGLRenderingContext.finish () блоков API WebGL выполнение до завершения всех ранее вызванных команд.

Редактировать: Если те не делают того, что вы ожидаете, то вы, вероятно, можете сделать минимальный вызов readPixels , который будет удерживаться для завершения конвейера.

...