Почему 2D-контекст холста не использует WebGL под капотом? - PullRequest
0 голосов
/ 09 мая 2020

Я довольно часто использовал 2D-контекст холста, а недавно начал изучать и WebGL.

Вопрос в заголовке пришел ко мне, когда я работал над учебником о том, как реализовать context.drawImage() из 2D-контекста в WebGL. Результатом было что-то, что работало как context.drawImage() (по крайней мере, довольно близко), но было намного быстрее, потому что использовалось WebGL.

Теоретически я считаю, что все в 2D-контексте холста можно эмулировать в WebGL, в результате в большом приросте производительности. Так почему же нет?

Я определенно не говорю об изменении какого-либо синтаксиса или чего-то еще. Мне очень нравится простота 2D-контекста. Но почему браузер не делает то, что делал этот учебник под капотом?

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

1 Ответ

1 голос
/ 09 мая 2020

Canvas2D действительно использует GPU под капотом, используя в основном тот же API, что и WebGL.

Вероятно, что если вы реализуете весь Canvas 2D spe c в WebGL, скорость будет примерно такой же. Canvas поддерживает такие вещи, как рисование с узорами , рисование с градиентами , контуры обрезки , линии с произвольной шириной, концами, стыками и т. Д. c ... Добавить все эти функции вашего Canvas реализованы в WebGL и могут иметь аналогичную скорость.

Причина, по которой WebGL может быть быстрее: (а) потому что вы можете отказаться от реализации функций, которые не собираетесь использовать, и (б) потому что вы можете оптимизировать, зная, что вы только собираетесь использовать определенные функции.

В качестве простого примера, на холсте вы можете нарисовать изображение с помощью drawImage(someImageElement, x, y). В WebGL вы сначала должны создать текстуру из изображения, а затем рисовать с использованием текстуры, чтобы вы вручную управляли этой текстурой. Canvas на самом деле должен делать то же самое. Он должен был загрузить изображение в текстуру, чтобы отрисовать его (при условии, что холст основан на графическом процессоре). Но он не знает, собираетесь ли вы снова рисовать изображение, поэтому он не может навсегда сохранить это изображение как текстуру. Простейшей реализацией было бы скопировать изображение в текстуру, нарисовать, а затем удалить текстуру. Я сомневаюсь, что это то, что делает холст, я предполагаю, что у него есть некоторый кеш текстур, созданных из изображений. Но дело в том, что это управление текстурами неявно, тогда как в WebGL оно явное, вы должны вручную управлять текстурами.

Другой пример - рисование фигур. В WebGL вы обычно решаете, какие фигуры рисовать во время инициализации, настраиваете все данные, необходимые для их рисования, а затем во время рендеринга вы просто используете фигуры, которые вы уже настроили. В Canvas чаще всего рисуют фигуры на лету, то есть каждый раз, когда вы хотите нарисовать фигуру, вы используете команды moveTo и lineTo для построения фигуры, которая эффективно выполняет всю работу каждый раз, когда вы визуализируете, а не как WebGL выполняет эту работу только во время инициализации.

Различия такие же, как и те, которые делают холст проще, а webgl быстрее.

Примечание: некоторые люди пытались реализовать canvas2d в WebGL здесь и здесь

...