WebGL如何避免长时间着色器编译暂停选项卡
我有一个巨大的着色器,它需要一分钟以上的时间来编译,在编译过程中会完全阻塞整个浏览器。据我所知,着色器编译不能是异步的,所以您可以在等待编译完成时运行其他WebGL命令 我已经尝试了以下方法:WebGL如何避免长时间着色器编译暂停选项卡,webgl,webgl2,Webgl,Webgl2,我有一个巨大的着色器,它需要一分钟以上的时间来编译,在编译过程中会完全阻塞整个浏览器。据我所知,着色器编译不能是异步的,所以您可以在等待编译完成时运行其他WebGL命令 我已经尝试了以下方法: 一段时间内不要使用该特定着色器-这不起作用,因为大多数其他WebGL命令将等待它完成,即使该着色器程序从未处于活动状态 使用另一个上下文-同上,但即使来自另一个上下文的WebGL命令也会导致暂停 在web worker中使用OffscreenCanvas——这也不能避免暂停,即使它在worker中,也会
- 一段时间内不要使用该特定着色器-这不起作用,因为大多数其他WebGL命令将等待它完成,即使该着色器程序从未处于活动状态
- 使用另一个上下文-同上,但即使来自另一个上下文的WebGL命令也会导致暂停
- 在web worker中使用OffscreenCanvas——这也不能避免暂停,即使它在worker中,也会暂停整个浏览器。即使我在命令链接程序以发出任何其他WebGL命令后等待几分钟,浏览器也会暂停(就好像在这段时间内什么也没发生一样)
let vertexShader = gl.createShader(gl.VERTEX_SHADER);
let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
let program = gl.createProgram();
gl.shaderSource(vertexShader, vertexSource);
gl.shaderSource(fragmentShader, fragmentSource);
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
let status = gl.getProgramParameter(program, gl.LINK_STATUS);
let programLog = gl.getProgramInfoLog(program);
在调用linkProgram后等待几分钟,即使在worker中也无济于事
最后要注意的是:我可以让使用OpenGL运行的windows游戏不受此影响(游戏正在运行,我开始在浏览器中编译此着色器,并且在浏览器暂停时游戏继续运行正常)更新
Chromium添加了扩展,允许您查询着色器是否已完成编译
不幸的是,截至2021年1月,只有Chromium(Chrome/Edge/Brave/等)实施了该计划
原始答案 没有好的解决办法 Windows上的浏览器使用DirectX,因为OpenGL在许多机器上默认不提供,而且浏览器所需的许多其他功能与OpenGL不兼容 DirectX编译着色器需要很长时间。只有微软能解决这个问题。Microsoft提供了HLSL着色器编译器的源代码,但它仅适用于DX12 有些人建议允许网页提供二进制着色器,但由于两个非常重要的原因,这种情况永远不会发生
1您作为文本GLSL传递给WebGL的着色器由浏览器编译,检查各种问题,如果任何WebGL规则被破坏,将被拒绝,然后重新写入以确保安全,插入错误解决方法,重新写入变量名称,添加夹紧指令,有时展开循环,各种各样的事情来确保你不会撞坏司机。您可以使用
WEBGL\u debug\u着色器
扩展查看实际发送到驱动程序的着色器
二进制着色器是您给驱动程序的一个blob,您没有机会检查它或验证它是否做了坏事,因为它是驱动程序专有的二进制。没有关于其中内容、格式的文档,它们可以随每个GPU和每个驱动程序而改变。你只要相信司机就行了。司机不值得信赖。最重要的是,它是在您的计算机上执行的不受信任的代码。这和下载random.exe并执行它们没有什么不同,因此不会发生这种情况
至于WebGPU,不,WebGL没有更多的安全风险。即使它使用二进制格式,该二进制格式也适用于WebGPU本身,而不是驱动程序。WebGPU将读取二进制文件,检查是否遵循所有规则,然后生成与用户GPU匹配的着色器。生成的着色器可以是GLSL、HLSL、MetalSL、SPIR-V,但与WebGL类似,只有在验证所有规则均已遵循后,它才会编写着色器,然后它编写的着色器(与WebGL一样)将包括变通方法、夹紧以及使着色器安全所需的任何其他方法。请注意,截至2018年11月30日,WebGPU的着色器格式尚未确定。谷歌和Mozilla正在推动二进制SPIR-V的子集,这是文本HLSL的一种变体
请注意,当浏览器显示“RATS!WebGL这是一个障碍”时,并不意味着驱动程序崩溃。相反,这几乎总是意味着GPU重置的时间太长。在Chrome中(不确定其他浏览器),当Chrome请求GPU(通过驱动程序)执行某项操作时,它会启动计时器。如果GPU没有在2-5秒内完成(不确定实际超时),Chrome将终止GPU进程。这包括编译着色器,由于DirectX需要花费最多的时间来编译,这就是为什么DirectX上出现的问题最多
在Windows上,即使Chrome没有这样做,Windows也会这样做。这主要是因为大多数GPU(可能都在2018年)不能像CPU那样多任务。这意味着,如果你给他们30分钟的工作时间,他们将不用花时间去做