【问题标题】:Headless puppeteer screenshot not rendering WebGL canvas无头木偶截图不渲染 WebGL 画布
【发布时间】:2021-05-03 17:59:13
【问题描述】:

我正在尝试在无头模式下使用 puppeteer 截取website (in which I control) 的屏幕截图。

问题是,我的网站上有一个 WebGL 画布不会以无头模式屏幕截图呈现(但可以在有头模式下工作)。

我在无头模式下得到的只是黑色 PNG。

我尝试将 WebGL 上下文参数更改为多种组合,但没有任何效果。

我正在使用 puppeteer 版本 5.5.0 和铬版本 88.0.4298.0

这是我的 puppeteer 爬虫代码:

const puppeteer = require("puppeteer");

const url = "https://phcs93.github.io/genesis/";

async function crawl () {
    const browser = await puppeteer.launch({
        headless: true,
        args: [
            '--no-sandbox', 
            '--disable-setuid-sandbox', 
            '--mute-audio'
        ]
    });
    const page = await browser.newPage();
    await page.goto(url, {
        "waitUntil": "networkidle0",
        "timeout": 0
    });
    await page.screenshot({ path: "screenshot.png" });
    await browser.close();
}

(async () => await crawl())();

这些是我在网站的 WebGL 上下文中使用的当前参数:

const gl = canvas.getContext("webgl2", {
    preserveDrawingBuffer: true,
    alpha: false,
    antialias: true,
    premultipliedAlpha: true
});

【问题讨论】:

  • 作为健全性检查,您是否尝试在截屏前添加等待。示例await new Promise(resolve => setTimeout(resolve, 5000));

标签: node.js canvas webgl puppeteer


【解决方案1】:

经过大量调试,我发现了问题:

在我的一个着色器 (gradient.glsl) 中,我有这个:

uniform float[256] breakpoints;
uniform vec4[256] colors;

改成这样,问题解决了:

uniform float[122] breakpoints;
uniform vec4[122] colors;

两个数组的任何高于 122 的值都不起作用。

现在更奇怪的部分来了,这行得通:

uniform float[244] breakpoints; // 245 or more wont work
// uniform vec4[122] colors;

这不起作用:

// uniform float[122] breakpoints;
uniform vec4[244] colors; // only 243 or less

除此之外我还没有测试过,看起来像无头模式的某种内存限制?

提示:可以使用 puppeteer 捕获页面中的所有控制台消息,只需在 page.goto 之前添加:

page.on('console', message => console.log(`${message.type().substr(0, 3).toUpperCase()} ${message.text()}`));
page.on('pageerror', ({ message }) => console.log(message));
page.on('response', response => console.log(`${response.status()} ${response.url()}`));
page.on('requestfailed', request => console.log(`${request.failure().errorText} ${request.url()}`));

这样做可以节省我大量的调试时间。

【讨论】:

  • 不同的 webgl 实现存在限制。您可以使用gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS)gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS) 查询最大统一向量。在用于片段着色器的 WebGL 中,只需要 16 个。对于顶点着色器 128。这意味着您的着色器可能无法在很多设备上运行。如果你想要大量数据,你应该使用textures
  • 至于 122/244 问题,请参阅 thisthis
猜你喜欢
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-07
  • 2019-05-07
  • 2023-01-19
  • 2017-11-18
  • 1970-01-01
相关资源
最近更新 更多