почему контекст webgl canvas использует гораздо больше памяти, чем 2d canvas?

#canvas #webgl

#холст #webgl

Вопрос:

1024×1024 2d canvas может использовать около 1024 * 1024 * 4 = 4M памяти, но контекст WebGL использует как минимум в 5-10 раз больше памяти.

 <!DOCTYPE html>
<html>
    <body>
    
        <div style="display:inline-block ;overflow: hidden;width: 512px;height: 512px;">
            <canvas id="canvas" width="1024" height="1024" style="border: red 1px solid;transform: scale(0.5); transform-origin: 0 0;">old version need update</canvas>
        </div>
    </body>

    <script>
        var ctx = window.document.getElementById("canvas").getContext("webgl")
        var gl = canvas.getContext("experimental-webgl");

    </script>

</html>
  

Ответ №1:

Возможно, есть несколько причин

По умолчанию webgl canvas сглажен.

Браузер выбирает объем, но проверяет

 const gl = document.createElement('canvas').getContext('webgl');
const samples = gl.getParameter(gl.SAMPLES) || 1;
console.log(`samples is ${samples} so this canvas is actually ${gl.canvas.width * samples} x ${gl.canvas.height * samples} pixels big internally`);  

На моей машине холст размером 300×150 на самом деле равен 1200×600, потому что именно так работает сглаживание, встроенное в графический процессор

Вы можете отключить сглаживание, передав antialias: false его при создании контекста

 const gl = document.createElement('canvas').getContext('webgl', {
  antialias: false,
});
const samples = gl.getParameter(gl.SAMPLES) || 1;
console.log(`samples is ${samples} so this canvas is actually ${gl.canvas.width * samples} x ${gl.canvas.height * samples} pixels big internally`);  

WebGL имеет двойную буферизацию

Таким образом, всегда будет выделено как минимум 2 буфера, буфер рисования (буфер, в который вы выполняете рендеринг) и копия, используемая для рендеринга страницы. Таким образом, даже при отключенном сглаживании будет 2 буфера, где в качестве 2D canvas может быть только 1 (то, что он делает для canvas 2D, зависит от браузера)

WebGL требует контекста GL и соответствующей поддержки

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

Комментарии:

1. большое спасибо, я не понимаю, что webgl использует ssaa для сглаживания. и на моей машине параметры равны 8.

2. Может ли разработчик управлять встроенными параметрами сглаживания webgl? Отключить образцы ssaa 8 ужасно, могу ли я установить параметр small samples, или мне придется самому выполнять сглаживание с помощью msaa или другой технологии сглаживания.

3. Вы не можете установить сглаживание холста, кроме как на false (выкл.) или true (пусть браузер решает). Вы можете визуализировать текстуру с помощью фреймбуфера и выполнять любую обработку, которую вы хотите, при рендеринге на холсте. Вы также можете сделать холст больше, чем он отображается, и получить билинейную фильтрацию при его компоновке. В WebGL2 вы можете создавать свои собственные буферы рендеринга с несколькими образцами, но не в WebGL1