web-dev-qa-db-ja.com

ヘッドレスでWebGLイメージをレンダリングするchrome GPUなし

GPUのないLinuxサーバーでWebGLでレンダリングされた画像をエクスポートしようとしています。これを行うには、ヘッドレスChromeを使用していますが、エクスポートされた画像は黒です( エクスポートされた画像の例ページのスクリーンショットを撮ると、 is black )。私はこれがなぜ起こっているのかを理解する助けを望んでいた。

画像をエクスポートするには、画像をキャンバスにレンダリングし、canvas.toDataURL('image/jpeg')を介してデータをエクスポートしてから、サーバーにデータを送信します。レンダリングにPixi.jsを使用しています。キャンバスレンダラーを使用すると、すべてがサーバー上で機能します。動作しないのはWebGLレンダリングです。 WebGLのレンダーがMacbookのChrome 63で正常に機能することに注意してください。

Chrome私は Puppeteer を使用しています。私がしているのは、ページを開いて、1秒間待ってから再び閉じることです。

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作者は6月にヘッドレスWebGLレンダリングが可能だと言った であり、 このChromiumの問題で確認された ので、何かが欠けていると思う。誰かが私が間違っていることを知っていますか?

私が試したいくつかのこと:

  • -disable-gpuを渡さない
  • --use-gl=swiftshader-webgl--use-gl=swiftshader--use-gl=osmesa
  • フルスクリーンのスクリーンショットを撮って、そのキャンバスだけかどうかを確認します。画面全体が真っ黒です。

バージョン

  • Chrome:linux-515411
  • 操り人形師:0.13.0
  • ノード:8.2.1
  • Linux:CentOS 7

これは、サーバーにインストールして、chromeを実行して( Source

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
24

premultipliedAlpha をfalseに設定することで、この問題を部分的に解決しました。 true(デフォルト)の場合、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かに関係なく、レンダリングされたイメージを見ることができるということです。

6

X11ライブラリのないシステムに影響する未解決のバグがあります: crbug.com/swiftshader/79 。 Chrome OSがSwiftShaderで実行されるのを防ぎますが、X11をサポートしていないヘッドレスLinuxシステムでも同じ問題が発生します。

幸いなことに、X11をインストールして実行することが可能です。どのパッケージが必要なライブラリを提供するか100%はわかりませんが、これらを試してください:xorg xserver-xorg xvfb libx11-dev libxext-dev libxext-dev:i386

最終的には、SwiftShaderのバグは修正されるため、X11は一切必要ありません。

6
Nicolas Capens

サーバーで実行し、そこで利用可能なGPUがない場合は、代わりに何かを使用する必要があります。

WebGL 1.0はOpenGL ES 2.0仕様に基づいており、これはOpenGL 2.1仕様に基づいています。ソフトウェアレンダラーを実装し、検証に使用されるMesaライブラリ( https://en.wikipedia.org/wiki/Mesa_(computer_graphics) )がありますベンダーによるOpenGLの実装。 3.1までのOpenGLをサポートしていると思いますが、私は間違っている可能性があり、現在ではさらに高いバージョンをサポートしています。

Mesaをドライバーとして* nixにインストールし、ソフトウェア実装を使用してOpenGLレンダリングを実行することができます。

ここで受け入れられた答えを確認することをお勧めします: chromeでwebglにmesaソフトウェアドライバーを使用させる方法 問題

1

これが役に立つかどうかはわかりませんが、WebGLコンテキストを作成するときに設定できるオプションがあります。ブラウザの実装に応じて、異なるデフォルト値を設定できます。

preserveDrawingBuffertrueに強制しようとしましたか?

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

[〜#〜] mdn [〜#〜] は、このオプションについて何を言っているかを示します。

preserveDrawingBuffer:値がtrueの場合、バッファはクリアされず、作成者によってクリアまたは上書きされるまでバッファの値が保持されます。

0
Tolokoban