WebGL是否可以模拟对gl.finish()的异步调用

问题描述 投票:13回答:1

WebGL很好并且异步,因为您可以发送一长串渲染命令而无需等待它们完成。但是,如果由于某种原因您需要等待渲染完成,则必须与gl.finish()同步执行。当然,如果gl.finish接受回调并立即返回会更好吗?

问题:有没有办法可靠地模拟这个?

用法案例:我将大量顶点渲染到大型离屏画布,然后使用drawImage将此大画布的部分复制到页面上的小画布。我实际上并没有使用gl.finish(),但drawImage()似乎具有相同的效果。在我的应用程序中,只有当用户执行操作(例如,单击按钮)时才会触发重新渲染,并且可能需要几百毫秒。如果在渲染期间浏览器仍然响应允许滚动等,那将是很好的。我特别关注Chrome解决方案,尽管在Firefox和Safari中也可以使用。

可能(坏)答案:你可以尝试估计渲染的时间长度,然后设置一个以调用gl.finish()开始的超时。但是,对所有大小的顶点缓冲区和所有用户可靠地进行此估计将非常棘手且不准确。

可能的(非)答案:requestAnimationFrame做我正在寻找的......但它不是,是吗?

2018年可能的答案:也许ImageBitmap API解决了这个问题 - 请参阅MDN docs

webgl
1个回答
5
投票

你已经部分地回答了你的答案:drawImage()确实具有类似于完成的行为,因为它在读回图像数据之前强制完成所有未完成的绘图命令。问题是,即使gl.finish()做了你想要的,等待渲染完成,你仍然会像现在一样使用它。渲染完成时,主线程将被阻止,从而中断用户与页面交互的能力。

理想情况下,在这种情况下你想要的是某种回调,它指示何时完成了一组绘制命令而没有实际阻塞等待它们。不幸的是,没有这样的回调(考虑到浏览器的内部工作方式,提供一个回复将会非常困难!)

在您的情况下,一个不错的中间地带可能是对您感觉图像准备就绪时进行一些智能估计。例如,一旦你在调用requestAnimationFrame之前调出了你的绘制调用旋转3或4个drawImages。如果你一直观察它需要更长时间(10帧?)然后旋转更长时间。这将允许用户继续正常与页面进行交互,并且在执行绘制图像时不会产生任何延迟,因为内容已完成渲染,或者因为您在渲染过程中执行同步步骤而导致延迟少得多。根据您网站的预期用途,非实时渲染甚至可能会在呈现之前旋转一整秒左右。

这当然不是一个完美的解决方案,我希望我有一个更好的答案。也许WebGL将来能够查询这种类型的状态,因为它在像你这样的情况下会很有价值,但是现在这可能是你能做到的最好的。

© www.soinside.com 2019 - 2024. All rights reserved.