wake-up-neo.net

Rendern von WebGL-Bildern in Headless Chrome ohne GPU

Ich versuche ein mit WebGL gerendertes Bild auf einem Linux-Server ohne GPU zu exportieren. Um dies zu tun, verwende ich Headless Chrome. Das exportierte Bild ist jedoch schwarz ( zum Beispiel exportiertes Bild , Ein Screenshot der Seite zeigt nur seine schwarze Leinwand ). Ich hoffte auf etwas Hilfe, um herauszufinden, warum das so ist.

Um das Bild zu exportieren, rendere ich das Bild in eine Leinwand, exportiere Daten über canvas.toDataURL('image/jpeg') und verbinde die Daten dann auf dem Server. Ich verwende Pixi.js für das Rendern. Wenn ich Canvas-Renderer verwende, funktioniert alles auf dem Server. Es ist WebGL-Rendering, das nicht funktioniert. Beachten Sie, dass das WebGL-Rendering in Chrome 63 auf einem Macbook einwandfrei funktioniert.

Um Chrome zu steuern, verwende ich Puppeteer . Ich öffne nur eine Seite, warte eine Sekunde und schließe sie wieder:

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));
    });
  })

Dies sind die Argumente, die der Puppenspieler an Chrome weitergibt:

[
  '--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'
]

Der Swiftshader-Autor sagte, dass im Juni Headless-WebGL-Rendering möglich ist und es scheint durch diese Chromium-Ausgabe bestätigt zu werden Ich denke, mir fehlt etwas. Hat jemand eine Idee, was ich falsch mache?

Ein paar Dinge, die ich ausprobiert habe:

  • Nicht übergeben --disable-gpu
  • --use-gl=swiftshader-webgl, --use-gl=swiftshader, --use-gl=osmesa
  • Machen Sie einen Screenshot im Vollbildmodus, um zu sehen, ob es nur Leinwand ist. Der gesamte Bildschirm ist nur schwarz.

Versionen

  • Chrome: Linux-515411
  • puppenspieler: 0,13,0
  • knoten: 8.2.1
  • Linux: CentOS 7

Das war es, was ich auf meinem Server installieren musste, um Chrome zum Laufen zu bringen ( 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
22

Also habe ich das Problem teilweise gelöst, indem ich premultipliedAlpha auf false gesetzt habe. Wenn dies wahr ist (Standardeinstellung), gibt toDataURL ein leeres Bild zurück. Bei false wird das gerenderte Bild zurückgegeben. 

<!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>

Interessant ist, wenn ich einen Screenshot mit puppeteer mache, kann ich das gerenderte Bild sehen, unabhängig davon, ob premultipliedAlpha wahr oder falsch ist.

6

Es gibt einen offenen Fehler, der Systeme ohne X11-Bibliotheken betrifft: crbug.com/swiftshader/79 . Es verhindert, dass Chrome OS mit SwiftShader ausgeführt wird. Das gleiche Problem tritt jedoch auch bei Linux-Headless-Systemen auf, die X11 nicht unterstützen.

Glücklicherweise sollte es möglich sein, X11 zu installieren und die Dinge zum Laufen zu bringen. Ich bin nicht 100% sicher, welche Pakete die erforderlichen Bibliotheken bereitstellen, aber probieren Sie diese: xorg xserver-xorg xvfb libx11-dev libxext-dev libxext-dev:i386

Eventuell wird der SwiftShader-Fehler behoben, so dass keinerlei X11 erforderlich ist.

5
Nicolas Capens

Wenn Sie es auf einem Server ausführen möchten und dort keine GPU verfügbar ist, müssen Sie stattdessen etwas verwenden.

WebGL 1.0 basiert auf den Spezifikationen von OpenGL ES 2.0, die auf den Spezifikationen von OpenGL 2.1 basieren. Es gibt eine Mesa-Bibliothek ( https://en.wikipedia.org/wiki/Mesa_(computer_graphics) ), die Software-Renderer implementiert und zur Validierung der OpenGL-Implementierung von Anbietern verwendet wird. Ich denke, es unterstützt OpenGL bis 3.1, aber ich kann mich irren und unterstützt jetzt die Version noch höher.

Es ist möglich, Mesa als Treiber in * nix zu installieren und OpenGL-Rendering mithilfe der Softwareimplementierung durchzuführen. 

Ich schlage vor, die akzeptierte Antwort hier zu überprüfen: wie man Chrome zwingt, den Mesa-Softwaretreiber für Webgl zu verwenden Ich bin mir ziemlich sicher, dass es Ihr Problem lösen wird

1

Ich weiß nicht, ob dies Ihnen helfen kann, aber es gibt Optionen, die Sie beim Erstellen eines WebGL-Kontexts festlegen können. Je nach Browserimplementierung können Sie unterschiedliche Standardwerte verwenden.

Haben Sie versucht, preserveDrawingBuffer auf true zu setzen?

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

Folgendes sagt MDN zu dieser Option:

preserveDrawingBuffer: Wenn der Wert true ist, werden die Puffer nicht gelöscht und behalten ihre Werte, bis sie vom Autor gelöscht oder überschrieben werden.

0
Tolokoban