Подтвердить что ты не робот

Рендеринг изображения WebGL в безголовом хроме без GPU

Я пытаюсь экспортировать изображение, созданное с помощью WebGL на сервере Linux без GPU. Для этого я использую безголовый Chrome, однако экспортированное изображение является черным (пример экспортированного изображения, снятие скриншота страницы показывает его простое полотно, которое является черным). Я надеялся на какую-то помощь в выяснении, почему это происходит.

Чтобы экспортировать изображение, я визуализую изображение в холст, экспортирую данные через canvas.toDataURL('image/jpeg'), а затем отправляю данные на сервер. Я использую Pixi.js для рендеринга, если я использую canvas renderer, тогда все работает на сервере; Это рендеринг WebGL не работает. Стоит отметить, что рендеринг WebGL отлично работает в Chrome 63 на Macbook.

Для управления Chrome я использую Puppeteer. Все, что я делаю, это открыть страницу, ждать секунды, а затем снова закрыть ее:

puppeteer
  .launch({
    args: [
      '--no-sandbox',
      '--disable-setuid-sandbox',
    ],
  })
  .then(browser => {
    return browser.newPage().then(page => {
      return page
        .goto(url)
        .then(() => page.waitFor(1000))
        .then(() => browser.close())
        .catch(err => console.error('Failed', err));
    });
  })

Это аргументы, которые кукловод передает в Chrome:

[
  '--disable-background-networking',
  '--disable-background-timer-throttling',
  '--disable-client-side-phishing-detection',
  '--disable-default-apps',
  '--disable-extensions',
  '--disable-hang-monitor',
  '--disable-popup-blocking',
  '--disable-prompt-on-repost',
  '--disable-sync',
  '--disable-translate',
  '--metrics-recording-only',
  '--no-first-run',
  '--remote-debugging-port=0',
  '--safebrowsing-disable-auto-update',
  '--enable-automation',
  '--password-store=basic',
  '--use-mock-keychain',
  '--user-data-dir=/tmp/puppeteer_dev_profile-GhEAXZ',
  '--headless',
  '--disable-gpu',
  '--hide-scrollbars',
  '--mute-audio',
  '--no-sandbox',
  '--disable-setuid-sandbox'
]

автор swiftshader сказал, что в июне можно сделать рендеринг без заголовка WebGL и кажется подтвержденный этой проблемой Chromium, поэтому я думаю, что я что-то упустил. У кого-нибудь есть идеи, что я делаю неправильно?

Несколько вещей, которые я пробовал:

  • Не проходит через --disable-gpu
  • --use-gl=swiftshader-webgl, --use-gl=swiftshader, --use-gl=osmesa
  • Взятие полного скриншота экрана, чтобы увидеть, просто ли его холст. Весь экран просто черный.

Версия

  • Chrome: linux-515411
  • puppeteer: 0.13.0
  • node: 8.2.1
  • Linux: CentOS 7

Это то, что мне нужно было установить на моем сервере, чтобы запустить хром (Источник)

yum install cups-libs dbus-glib libXrandr libXcursor libXinerama cairo cairo-gobject pango ffmpeg
rpm -ivh --nodeps http://mirror.centos.org/centos/7/os/x86_64/Packages/atk-2.22.0-3.el7.x86_64.rpm
rpm -ivh --nodeps http://mirror.centos.org/centos/7/os/x86_64/Packages/at-spi2-atk-2.22.0-2.el7.x86_64.rpm
rpm -ivh --nodeps http://mirror.centos.org/centos/7/os/x86_64/Packages/at-spi2-core-2.22.0-1.el7.x86_64.rpm
rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/g/GConf2-3.2.6-7.fc20.x86_64.rpm
rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/l/libXScrnSaver-1.2.2-6.fc20.x86_64.rpm
rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/l/libxkbcommon-0.3.1-1.fc20.x86_64.rpm
rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/l/libwayland-client-1.2.0-3.fc20.x86_64.rpm
rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/l/libwayland-cursor-1.2.0-3.fc20.x86_64.rpm
rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/g/gtk3-3.10.4-1.fc20.x86_64.rpm
rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/16/Fedora/x86_64/os/Packages/gdk-pixbuf2-2.24.0-1.fc16.x86_64.rpm
4b9b3361

Ответ 1

Итак, я частично решил проблему, установив premultipliedAlpha значение false. Когда оно истинно (по умолчанию), toDataURL вернет пустое изображение. Когда false, он возвращает отображаемое изображение.

<!DOCTYPE html>
<html>
<body>
  <canvas id="canvas" width="1080" height="1080"></canvas>
  <script type="text/javascript">
    var canvas = document.getElementById('canvas');
    var gl = canvas.getContext('webgl', {
        premultipliedAlpha: false
    });

    gl.viewportWidth = canvas.width;
    gl.viewportHeight = canvas.height;
    gl.clearColor(0.99, 0, 1, 1);
    gl.clear(gl.COLOR_BUFFER_BIT);

    var IMAGE_PREFIX = 'data:image/png;base64,';
    var image = canvas.toDataURL('image/png').substring(IMAGE_PREFIX.length);

    // save(image)
  </script>
</body>
</html>

Что интересно, если я снимаю скриншот с помощью puppeteer, я вижу визуализированное изображение, независимо от того, является ли premultipliedAlpha true или false.

Ответ 2

Существует открытая ошибка, которая затрагивает системы без библиотек X11: crbug.com/swiftshader/79. Это предотвращает запуск Chrome OS с помощью SwiftShader, но такая же проблема также возникает и в безголовой системе Linux, у которой нет поддержки X11.

К счастью, должно быть возможно установить X11 и запустить все. Я не уверен на 100%, какие пакеты предоставляют необходимые библиотеки, но попробуйте: xorg xserver-xorg xvfb libx11-dev libxext-dev libxext-dev:i386

В конце концов ошибка SwiftShader будет исправлена, поэтому она не потребует X11 вообще.

Ответ 3

Если вы хотите запустить его на сервере и не иметь там графического процессора, вам нужно использовать что-то вместо него.

WebGL 1.0 основан на спецификации OpenGL ES 2.0, которая основана на спецификации OpenGL 2.1. Существует библиотека Mesa (https://en.wikipedia.org/wiki/Mesa_(computer_graphics)), которая реализует средство визуализации программного обеспечения и используется для проверки реализации OpenGL поставщиками. Я думаю, что он поддерживает OpenGL до 3.1, но я могу ошибаться, и теперь он поддерживает версию даже более высокого уровня.

Возможно установить Mesa в качестве драйвера в * nix и сделать его рендеринг OpenGL с использованием программного обеспечения.

Я предлагаю проверить принятый ответ здесь: как заставить хром использовать программный драйвер mesa для webgl Я уверен, что он решит вашу проблему

Ответ 4

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

Вы пытались заставить preserveDrawingBuffer true?

var gl = canvas.getContext( "webgl", {
    preserveDrawingBuffer: true
});

Вот что MDN говорит об этой опции:

preserveDrawingBuffer. Если значение равно true, буферы не очищаются и сохраняют свои значения до тех пор, пока не будут очищены или перезаписаны автором.